OVH Cloud OVH Cloud

problem de performance avec la sérialisation ?

4 réponses
Avatar
Jean Bon
hello

j'ai une application qui gère un arbre d'object. chaque object
dans l'arbre possède pas mal de fields et parmi ces fields il
y a tous le temps des références sur des *ancêtres* dans
l'arbre

mon problem est que je sérialize bcp cet arbre en utilisant le
binary formater.

un ex très simplifié de classes est ci-dessous. En supposant
qu'une instance *a* de A est la racine de l'arbre, je vois au
debugger que quand je lance la sérialization de cet *a*, on
passe deux fois dans le GetObjectData de cet *a*, une fois
quand l'object lui-même est sérialisé et une fois quand sa
référence dans B est sérialisée. Ainsi dans mon application,
on peut passer jusqu'à une centaine de fois dans cette method
pour un objet donné si bcp d'autres objects ont des références
sur lui ...

première question, je me demandais si cétait normal, pourquoi
ne passe t'on pas qu'une fois dans ce GetObjectData (sachant
qu'à chaque fois on remplit le dictionnaire SerializationInfo),
est ce que ça ne suffirait pas au formatter de n'y passer qu'une
fois ? est ce qu'il ne peut pas savoir qu'il est déjà en train ou
qu'il a déjà sérializé l'objet ?

sachant que mon arbre a de nombreuses références croisées,
je pense ça peut être un problem de performance ou au moins
je vois là que je pourrais les améliorer, voyez vous une autre
solution que de ne pas mettre toutes ces références dans les
SerializationInfo à la sérialization et de toutes les refaire sur
un OnDeserialization de la racine de mon arbre par exemple ?

Dernière question, est ce que la sésrialization par défaut (ie
ne pas implementer ISerializable, et mettre uniquement les
attributs Serializable) est meilleure en performance ?

merci pour tout :)


[Serializable]
class A : ISerializable
{
private string s1, s2;
protected A(SerializationInfo info, StreamingContext ctx)
{
s1= info.GetString("s1");
s2= info.GetString("s2");
}
protected void GetObjectData(SerializationInfo info, StreamingContext ctx)
{
info.AddValue("s1", typeof(string));
info.AddValue("s2", typeof(string));
}
}

[Serializable]
class B : ISerializable
{
private int i1, i2;
private A parent;
protected B(SerializationInfo info, StreamingContext ctx)
{
i1= (int)info.GetInt32("is1");
i2= info.GetInt32("i2");
parent = (A) GetValue("parent", typeof(A));
}
protected void GetObjectData(SerializationInfo info, StreamingContext ctx)
{
info.AddValue("i1", i1);
info.AddValue("i2", i2);
info.AddValue("parent", parent);
}
}

4 réponses

Avatar
Ambassadeur Kosh
bon, je n'aime pas precher pour la paroisse de Saint Bricolo, mais en
l'occurence, pourquoi ne pas envisager ton propre mécanisme de sérialization
?
avec GetType, tu as tout ce qu'il te faut pour faire à peu de frais un tel
systeme. des attributs que tu interpreteras avec ton mécanisme guideront le
processus.

il se pourrait bien que tu améliores l'efficacité du truc. et il se pourrait
égallement que tu découvres certains cas ou ce que tu as observé prend toute
son utilité.
Avatar
Simon Mourier [MS]
Vous auriez sans doute intêret à changer la façon dont vous sérialisez tout,
par exemple en créant un objet spécial de sérialisation, qui tiendrait

1) les données (pères, fils, etc...)
2) les relations (qui est fils de qui, qui est père de qui, etc...)

Ce qui vous permet de ne tout sérialiser qu'une fois. Si vous observez la
sérialisation d'un Dataset par exemple, vous verrez que c'est ce qui est
fait, d'un coté les tables, et de l'autre coté les relations entre tables.

Simon.

"Jean Bon" a écrit dans le message de news:
423c9d0b$0$22874$
hello

j'ai une application qui gère un arbre d'object. chaque object
dans l'arbre possède pas mal de fields et parmi ces fields il
y a tous le temps des références sur des *ancêtres* dans
l'arbre

mon problem est que je sérialize bcp cet arbre en utilisant le
binary formater.

un ex très simplifié de classes est ci-dessous. En supposant
qu'une instance *a* de A est la racine de l'arbre, je vois au
debugger que quand je lance la sérialization de cet *a*, on
passe deux fois dans le GetObjectData de cet *a*, une fois
quand l'object lui-même est sérialisé et une fois quand sa
référence dans B est sérialisée. Ainsi dans mon application,
on peut passer jusqu'à une centaine de fois dans cette method
pour un objet donné si bcp d'autres objects ont des références
sur lui ...

première question, je me demandais si cétait normal, pourquoi
ne passe t'on pas qu'une fois dans ce GetObjectData (sachant
qu'à chaque fois on remplit le dictionnaire SerializationInfo),
est ce que ça ne suffirait pas au formatter de n'y passer qu'une
fois ? est ce qu'il ne peut pas savoir qu'il est déjà en train ou
qu'il a déjà sérializé l'objet ?

sachant que mon arbre a de nombreuses références croisées,
je pense ça peut être un problem de performance ou au moins
je vois là que je pourrais les améliorer, voyez vous une autre
solution que de ne pas mettre toutes ces références dans les
SerializationInfo à la sérialization et de toutes les refaire sur
un OnDeserialization de la racine de mon arbre par exemple ?

Dernière question, est ce que la sésrialization par défaut (ie
ne pas implementer ISerializable, et mettre uniquement les
attributs Serializable) est meilleure en performance ?

merci pour tout :)


[Serializable]
class A : ISerializable
{
private string s1, s2;
protected A(SerializationInfo info, StreamingContext ctx)
{
s1= info.GetString("s1");
s2= info.GetString("s2");
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("s1", typeof(string));
info.AddValue("s2", typeof(string));
}
}

[Serializable]
class B : ISerializable
{
private int i1, i2;
private A parent;
protected B(SerializationInfo info, StreamingContext ctx)
{
i1= (int)info.GetInt32("is1");
i2= info.GetInt32("i2");
parent = (A) GetValue("parent", typeof(A));
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("i1", i1);
info.AddValue("i2", i2);
info.AddValue("parent", parent);
}
}



Avatar
Jean Bon
hello
merci de votre aide
bon j'ai une petite appli pour tenter de bencher les différentes
solutions. donc apparament dans l'ordre
-la sérialization que vous proposez est la meilleure
-après vient la sérialization par défaut
-et en dernière position la custom sérialization que j'avais
implémenté

je voudrais quand même bien comprendre pourquoi et comment la
sésrialization par défaut est meilleure que la sérialization custom
que j'avais implémentée ...

en tous cas merci, aussi à Ambassadeur Kosh :))


"Simon Mourier [MS]" wrote in message
news:
Vous auriez sans doute intêret à changer la façon dont vous sérialisez
tout, par exemple en créant un objet spécial de sérialisation, qui
tiendrait

1) les données (pères, fils, etc...)
2) les relations (qui est fils de qui, qui est père de qui, etc...)

Ce qui vous permet de ne tout sérialiser qu'une fois. Si vous observez la
sérialisation d'un Dataset par exemple, vous verrez que c'est ce qui est
fait, d'un coté les tables, et de l'autre coté les relations entre tables.

Simon.

"Jean Bon" a écrit dans le message de news:
423c9d0b$0$22874$
hello

j'ai une application qui gère un arbre d'object. chaque object
dans l'arbre possède pas mal de fields et parmi ces fields il
y a tous le temps des références sur des *ancêtres* dans
l'arbre

mon problem est que je sérialize bcp cet arbre en utilisant le
binary formater.

un ex très simplifié de classes est ci-dessous. En supposant
qu'une instance *a* de A est la racine de l'arbre, je vois au
debugger que quand je lance la sérialization de cet *a*, on
passe deux fois dans le GetObjectData de cet *a*, une fois
quand l'object lui-même est sérialisé et une fois quand sa
référence dans B est sérialisée. Ainsi dans mon application,
on peut passer jusqu'à une centaine de fois dans cette method
pour un objet donné si bcp d'autres objects ont des références
sur lui ...

première question, je me demandais si cétait normal, pourquoi
ne passe t'on pas qu'une fois dans ce GetObjectData (sachant
qu'à chaque fois on remplit le dictionnaire SerializationInfo),
est ce que ça ne suffirait pas au formatter de n'y passer qu'une
fois ? est ce qu'il ne peut pas savoir qu'il est déjà en train ou
qu'il a déjà sérializé l'objet ?

sachant que mon arbre a de nombreuses références croisées,
je pense ça peut être un problem de performance ou au moins
je vois là que je pourrais les améliorer, voyez vous une autre
solution que de ne pas mettre toutes ces références dans les
SerializationInfo à la sérialization et de toutes les refaire sur
un OnDeserialization de la racine de mon arbre par exemple ?

Dernière question, est ce que la sésrialization par défaut (ie
ne pas implementer ISerializable, et mettre uniquement les
attributs Serializable) est meilleure en performance ?

merci pour tout :)


[Serializable]
class A : ISerializable
{
private string s1, s2;
protected A(SerializationInfo info, StreamingContext ctx)
{
s1= info.GetString("s1");
s2= info.GetString("s2");
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("s1", typeof(string));
info.AddValue("s2", typeof(string));
}
}

[Serializable]
class B : ISerializable
{
private int i1, i2;
private A parent;
protected B(SerializationInfo info, StreamingContext ctx)
{
i1= (int)info.GetInt32("is1");
i2= info.GetInt32("i2");
parent = (A) GetValue("parent", typeof(A));
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("i1", i1);
info.AddValue("i2", i2);
info.AddValue("parent", parent);
}
}







Avatar
Jean Bon
"Jean Bon" wrote in message
news:423dbed6$0$31419$
hello
merci de votre aide
bon j'ai une petite appli pour tenter de bencher les différentes



... j'ai fait ...

solutions. donc apparament dans l'ordre
-la sérialization que vous proposez est la meilleure
-après vient la sérialization par défaut
-et en dernière position la custom sérialization que j'avais
implémenté

je voudrais quand même bien comprendre pourquoi et comment la
sésrialization par défaut est meilleure que la sérialization custom
que j'avais implémentée ...

en tous cas merci, aussi à Ambassadeur Kosh :))


"Simon Mourier [MS]" wrote in message
news:
Vous auriez sans doute intêret à changer la façon dont vous sérialisez
tout, par exemple en créant un objet spécial de sérialisation, qui
tiendrait

1) les données (pères, fils, etc...)
2) les relations (qui est fils de qui, qui est père de qui, etc...)

Ce qui vous permet de ne tout sérialiser qu'une fois. Si vous observez la
sérialisation d'un Dataset par exemple, vous verrez que c'est ce qui est
fait, d'un coté les tables, et de l'autre coté les relations entre
tables.

Simon.

"Jean Bon" a écrit dans le message de news:
423c9d0b$0$22874$
hello

j'ai une application qui gère un arbre d'object. chaque object
dans l'arbre possède pas mal de fields et parmi ces fields il
y a tous le temps des références sur des *ancêtres* dans
l'arbre

mon problem est que je sérialize bcp cet arbre en utilisant le
binary formater.

un ex très simplifié de classes est ci-dessous. En supposant
qu'une instance *a* de A est la racine de l'arbre, je vois au
debugger que quand je lance la sérialization de cet *a*, on
passe deux fois dans le GetObjectData de cet *a*, une fois
quand l'object lui-même est sérialisé et une fois quand sa
référence dans B est sérialisée. Ainsi dans mon application,
on peut passer jusqu'à une centaine de fois dans cette method
pour un objet donné si bcp d'autres objects ont des références
sur lui ...

première question, je me demandais si cétait normal, pourquoi
ne passe t'on pas qu'une fois dans ce GetObjectData (sachant
qu'à chaque fois on remplit le dictionnaire SerializationInfo),
est ce que ça ne suffirait pas au formatter de n'y passer qu'une
fois ? est ce qu'il ne peut pas savoir qu'il est déjà en train ou
qu'il a déjà sérializé l'objet ?

sachant que mon arbre a de nombreuses références croisées,
je pense ça peut être un problem de performance ou au moins
je vois là que je pourrais les améliorer, voyez vous une autre
solution que de ne pas mettre toutes ces références dans les
SerializationInfo à la sérialization et de toutes les refaire sur
un OnDeserialization de la racine de mon arbre par exemple ?

Dernière question, est ce que la sésrialization par défaut (ie
ne pas implementer ISerializable, et mettre uniquement les
attributs Serializable) est meilleure en performance ?

merci pour tout :)


[Serializable]
class A : ISerializable
{
private string s1, s2;
protected A(SerializationInfo info, StreamingContext ctx)
{
s1= info.GetString("s1");
s2= info.GetString("s2");
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("s1", typeof(string));
info.AddValue("s2", typeof(string));
}
}

[Serializable]
class B : ISerializable
{
private int i1, i2;
private A parent;
protected B(SerializationInfo info, StreamingContext ctx)
{
i1= (int)info.GetInt32("is1");
i2= info.GetInt32("i2");
parent = (A) GetValue("parent", typeof(A));
}
protected void GetObjectData(SerializationInfo info, StreamingContext
ctx)
{
info.AddValue("i1", i1);
info.AddValue("i2", i2);
info.AddValue("parent", parent);
}
}