Bonjour,
le c# est -il assez suffisant en terme de performance pour le calcul scientifique ?
J'ai peur que le machine virtuelle plombe les performances...
Merci
Bonjour,
le c# est -il assez suffisant en terme de performance pour le calcul scientifique ?
J'ai peur que le machine virtuelle plombe les performances...
Merci
J'ai eu l'occasion de travailler dans le domaine financier à ma précédente job et je dois dire que la vitesse n'était pas vraiment le problème de .NET. Une fois le programme optimisé, les performances étaient similaires aux programmes C++ / Matlab. Le compilateur JIT fait une très bonne job.
Cela étant dit, j'ai rencontré certaines difficultés lors qu'il s'agissait de simulations qui nécessitaient des tableaux de quelques millions de valeurs qui peut avoir comme fâcheuse conséquence de fragmenter ton heap et de lever des OutOfMemoryException.
Il y a souvent incompréhension par rapport à cette notion de machine virtuelle mentionnée par Java (MS évite quant à lui l'utilisation de ce terme). Il n'y a pas de virtualisation ou autre et le pseudo-code sera compilé en natif (x86/x64). Le code asm généré est en pratique proche de celui d'un code écrit en C++ et les différences de performances généralement faibles ou très faibles.
Pour du calcul scientifique, le seul et unique surpoids pertinent devrait être les vérifications des indices sur les tableaux. En C++ "montableau[i]" donne le code assembleur suivant :
En C#, en substance, tu as le code assembleur suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Stocker la valeur de "montableau" (une séquence de valeurs) dans A Stocker la valeur de "i" dans B C = A + B Charger la valeur à l'adresse située dans C.
Note toutefois que ces vérifications de dépassement de capacité ne sont pas émises dans le code suivant car elles sont superflues :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Stocker la valeur de "montableau" (une longueur, suivie d'une séquence de valeurs) dans A Stocker la longueur de A (valeur située à l'adresse A) dans B Stocker la valeur de "i" dans C Si i >= longueur, sauter au label dépassement de capacité D = A + C + offset_début_séquence Charger la valeur à l'adresse située dans D.
Attention, il faut vraiment utiliser une boucle for telle qu'écrite ci-dessus pour que le compilo C# comprenne que les vérifications de capacité ne sont pas nécessaires. Il ne faut par exemple pas essayer de stocker la longueur dans une variable avant la boucle for, le compilateur ne reconnaîtrait pas ce motif comme sûr.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 for(int i = 0; i <= montableau.Length; i++) { montableau[i] = montableau[i] * 2; }
Enfin, il est toujours possible d'utiliser des opérations unsafe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 fixed(int* ptr = montableau) { int* p = ptr; for(int i = 0; i < 1000; i++) { *p = *p + 1; p++; } }
Quelques dernières remarques:
* Si tu crains d'être limité par les accès mémoire plutôt que par la vitesse de traitement, sache que toute instance d'une classe dotnet a un en-tête de 10 octets. Les structures, quant à elles, n'ont pas ce genre de problèmes. Mais les méthodes dont un des paramètres est une structure ne sont jamais "inlined" par le compilateur.
* Outre les vérifications de capacités, un surpoids important est la gestion automatisée de la mémoire : chaque allocation nécessite un référencement dans le ramasse-miettes ; chaque assignation/désassignation/fin de portée d'une variable nécessite une incrémentation/décrémentation du compteur de références ; le ramasse-miettes doit parfois interrompre ton code pour faire son boulot.
* En plus des surpoids inhérents à dotnet et à la gestion automatisée de la mémoire, le compilateur C# est moins efficace que le compilateur C++. Pour du pur calcul, tu auras donc forcément une différence de performances. Toutefois, celle-ci n'a rien de gigantesque, à toi de voir selon tes besoins.
* Enfin, sois conscient que même en C++, on utilise en pratique souvent des structures de données qui ajoutent au final les mêmes surpoids au code que ceux ajoutés par dotnet en standard.
J'ajouterais que .Net mets a ta disposition des bibliothèques de parallèlisation (PLINQ) qui simplifient le développement multithreadé
Retrouvez moi sur :
Mon Espace Developpez.com-------------------------------
Dvp.NET, une librairie open-source de composants .NET
Mon blog: Up there in the code----------------------------
Twitter: NatMarchand
Ma société: So@t
Showrizo : Suivez votre planning de séries télé sous Windows 8
Partager