web-dev-qa-db-fra.com

Déclarer une variable à l'intérieur ou à l'extérieur d'une boucle foreach: quelle est la plus rapide / meilleure?

Lequel d'entre eux est le plus rapide/le meilleur?

Celui-là:

List<User> list = new List<User>();
User u;

foreach (string s in l)
{
    u = new User();
    u.Name = s;
    list.Add(u);
}

Ou celui-ci:

List<User> list = new List<User>();

foreach (string s in l)
{
    User u = new User();
    u.Name = s;
    list.Add(u);
}

Mes compétences de débutant me disent que la première est meilleure, mais un de mes amis me dit que je me trompe, mais ne peut pas me donner une bonne raison pour laquelle la seconde est meilleure.

Y a-t-il une différence de performance?

81
Marcus

En termes de performances, les deux exemples sont compilés dans le même IL, il n'y a donc pas de différence.

La seconde est meilleure, car elle exprime plus clairement votre intention si u n'est utilisé qu'à l'intérieur de la boucle.

99
dtb

Dans tous les cas, la meilleure façon serait d'utiliser un constructeur qui prend un nom ... ou, sinon, d'exploiter la notation accolade:

foreach (string s in l)
{
    list.Add(new User(s));
}

ou

foreach (string s in l)
{
    list.Add(new User() { Name = s });
}

ou encore mieux, LINQ:

var list = l.Select( s => new User { Name = s});

Maintenant, alors que votre premier exemple pourrait, dans certains cas, être imperceptiblement plus rapide, le second est meilleur car il est plus lisible, et le compilateur peut ignorer la variable (et l'omettre complètement) car il n'est pas utilisé en dehors du foreach portée.

14
Tordek

Une déclaration n'entraîne l'exécution d'aucun code, il ne s'agit donc pas d'un problème de performances.

Le deuxième est ce que vous voulez dire, et vous êtes moins susceptible de faire une erreur stupide si vous le faites de la deuxième façon, alors utilisez-le. Essayez toujours de déclarer des variables dans la plus petite étendue nécessaire.

Et en plus, la meilleure façon est d'utiliser Linq:

List<User> users = l.Select(name => new User{ Name = name }).ToList();
6
Mark Byers

Chaque fois que vous avez une question sur les performances, la seule chose à faire est de mesurer - faites une boucle autour de votre test et chronométrez-le.

Pour répondre à votre question - sans mesurer :-) ou en regardant l'ilasme généré - aucune différence ne serait perceptible dans un nombre significatif d'itérations et l'opération la plus coûteuse dans votre code, il y aura probablement l'allocation d'utilisateurs par quelques commandes de magnitude, alors concentrez-vous sur la clarté du code (comme vous devriez en général) et allez avec 2.

Oh, il est tard et je suppose que j'essaie juste de dire ne vous inquiétez pas de ce genre de chose ou ne vous laissez pas prendre dans des détails comme celui-ci.

K

5
Kevin Shea

Le 2ème est meilleur. Vous voulez avoir un nouvel utilisateur à chaque itération.

1
Jarrett Widman

Techniquement, le premier exemple permettra d'économiser quelques nanosecondes car le cadre de la pile n'aura pas à être déplacé pour allouer une nouvelle variable, mais c'est une quantité de temps CPU si minime que vous ne le remarquerez pas, c'est si le compilateur ne le fait pas optimiser toute différence loin de toute façon.

1
Erik Funkenbusch

Dans ce scénario, la deuxième version est meilleure.

En général, si vous avez seulement besoin d'accéder à la valeur dans le corps de l'itération, choisissez la deuxième version. D'un autre côté, s'il y a un état final, la variable se maintiendra au-delà du corps de la boucle, puis déclarez puis utilisez la première version.

1
csj

Il ne devrait pas y avoir de différence de performance perceptible.

0
Jacob Adams
0
Sunil