Boucle imbriquée très très lente

Signaler
Messages postés
39
Date d'inscription
mardi 26 août 2008
Statut
Membre
Dernière intervention
19 août 2012
-
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
-
Bonjour,

Pourquoi un code C# s'exécute bien plus lentement qu'un code C++ similaire?

Voici un code C++ :
#include <stdio.h>
int main() {
int i, j, k, l, m, n, o, p, q, r;
for (i = 0; i < 1000000; i++)
for (j = 0; j < 1000000; j++)
for (k = 0; k < 1000000; k++)
for (l = 0; l < 1000000; l++)
for (m = 0; m < 1000000; m++)
for (n = 0; n < 1000000; n++)
for (o = 0; o < 1000000; o++)
for (p = 0; p < 1000000; p++)
for (q = 0; q < 1000000; q++)
for (r = 0; r < 1000000; r++);
printf("END");
return 0;
}


Ce code s'exécute instantanément.

Voici le même code en C#, qui lui s'exécute en quelques secondes :
namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
int i, j;
for (i = 0; i < 1000000; i++)
for (j = 0; j < 10000; j++);
Console.WriteLine("END");
}
}
}

11 réponses

Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Salut, tu peux comparer le temps d’exécution de ces 2 codes mais tu ne peux pas comparer le temps d’exécution de ces 2 programmes (*.exe) une application .NET fait beaucoup de chose au démarrage, comme par exemple charger le runtime en mémoire et jit-compiler le code IL lors du 1er passage dans la boucle.
Messages postés
39
Date d'inscription
mardi 26 août 2008
Statut
Membre
Dernière intervention
19 août 2012

dans les 2 cas si j'affiche BEGIN avant le premier for, l'affichage du END après le BEGIN sera instantané en C++ et non en C#. Le problème reste donc le même...
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
tu as compilé le c# en Release ? ça donne quoi avec Write à la place de Writeline ?
Messages postés
39
Date d'inscription
mardi 26 août 2008
Statut
Membre
Dernière intervention
19 août 2012

J'ai compilé les 2 en Release.
Avec le Write ça ne change rien.
La différence d'exécution est de quelques minutes si dans le code C# je met
for (j = 0; j < 1000000; j++);
à la place de
for (j = 0; j < 10000; j++);
Messages postés
39
Date d'inscription
mardi 26 août 2008
Statut
Membre
Dernière intervention
19 août 2012

Le problème c'est que le C++ me fait 10 boucles imbriquées de 1000000 d'itérations chacune alors que le C# n'arrive pas à en faire 2 dans le même temps
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
J'ai regardé rapidement le code de la fonction Console.Write(Line), rien n'est fait pour que ce soit rapide, la chaine est recopiée dans un tableau de char.. la version Write( char[ ] buffer )qui s'approche plus du comportement de printf doit être bien plus rapide si on crée qu'une seule fois le tableau { 'E','N','D' }.
Messages postés
39
Date d'inscription
mardi 26 août 2008
Statut
Membre
Dernière intervention
19 août 2012

Mon dieu... sans les printf et Console.Write c'est pareil... N'avez-vous donc pas vu les boucles for ? Dans l'un, 10 boucles ; dans l'autre, 2... Je crois rêver là.
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
42
Salut

En fait, je suis étonné par la vitesse du programme C++, pas par la "lenteur" du programme C#.

Ton programme C++ est tout de même censé faire 10^54 incrémentations et 10^54 condiitions. S'il fait ça aussi vite, je pense que c'est dû à de l'optimisation de la part du compilateur.
Côté C#, je viens de tester à l'instant, le code n'a aucune optimisation. Il va bien faire (dans le cas que tu présentes) 10^10 boucles.

Ce qui serait intéressant, ce serait soit de décompiler le C++ et de voir si tu as toujours tes boucles, soit empêcher le compilateur son optimisation en ajoutant une instruction dans tes boucles. (je ne peux pas le tester moi-même, je n'ai pas de compilo C++ sous la main)

Genre ajoute une variable
bool val = false;
et au bout de tes boucles, ajoute un
val = !val;

Côté C#, ça ne change pas grand chose. Et côté C++ ?

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
ah mais j'avais pas vu, tu as mis un point virgule à ta dernière boucle for C++ !
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Je comprends mieux pourquoi mes explications sur Write te convenait pas ^^ c'est pas le sujet.
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
34
Du coup maintenant que je comprends la question, effectivement je ne vois qu'une chose c'est que le compilo C++ à supprimé les boucles "for" voyant que les variables n'étaient jamais utilisées par la suite.