Microsoft CLR um Faktor 300 zu langsam?

03/05/2009 - 23:19 von Markus Schaber | Report spam
Hallo,

Ich habe das Problem, dass Geometrie-Berechnungen mit NTS[1] extrem
langsam ablaufen. Ich dachte zuerst, das Problem wàre durch Fehler bei
der Portierung von JTS[2], das ich nicht gar so langsam in Erinnerung
hatte, nach .NET verursacht worden.

Allerdings hab ich dann festgestellt, dass die selbe C#-.Exe unter
Windows in der Mono Runtime um ca. Faktor 300 schneller làuft, als in
der Microsoft Runtime, und damit zumindest in dieselbe Größenordnung
kommt, wie die Java Implementierung.

Ich hab ein Programm geschrieben[3], das eine topologisch àhnliche
Geometrie baut, wie die problematischen (die ich aus rechtlichen
Gründen nicht hier posten darf) - allerdings haben wir da noch
schlimmere Kandidaten, z. B. eine mit über 900k Stützpunkten und über
6700 innere Ringe.

Dann wird die Validitàt dieser Geometrie mittels NTS / JTS überprüft,
und die Zeit dazu gestoppt. Der Geschwindikgeitsunterschied ist so
krass, dass ich mich zuerst gar nicht getraut habe, das zu
veröffentlichen, und es auf einer zweiten Maschine reproduziert habe.

Um die Einflüsse des Garbage Collectors auszuschließen, habe ich alle 4
dokumentierten Garbage-Collector-Methoden der Microsoft CLR von .NET
3.5 getestet, und es mit Mono und Java verglichen.

Die Ergebnisse gibts unter
http://schabi.de/temp/clr/SpeedComp...Linear.jpg und anders skaliert
unter http://schabi.de/temp/clr/SpeedComp...thmic.jpeg

Der Testlauf mit dem LowLatencyGC ist mit OutOfMemoryException
abgebrochen, den mit dem BatchGC habe ich aus Geduldsgründen
vorzeitig beendet, da die Kurve wohl analog zum InteractiveGC
weiterlaufen wird.

Die Rechner waren ansonsten "idle", allerdings mit diversen
Hintergrundprozessen etc., was allerdings bei der Größenordung der
Unterschiede kaum ins Gewicht fallen dürfte. Die leichten Abweichungen
der Stützpunktzahl bei der Java-Version ergeben sich wohl aus leicht
abweichenden Algorithmen, da NTS Trunk auf JTS 1.7/1.8 basiert, wàhrend
ich JTS 1.10 verwendet habe - diese Unterschiede sollten allerdings
ebenfalls Größenordnungsmàßig nicht ins Gewicht fallen, und erklàren
nicht die Differenz zwischen Mono und der MS CLR.

Unter http://schabi.de/temp/clr/ gibt es alle Daten und Angaben, mit
denen man das Problem reproduzieren können müsste.



[1] http://code.google.com/p/nettopologysuite/

[2] http://sourceforge.net/projects/jts-topo-suite/

[3] http://schabi.de/temp/clr/Program.cs
http://schabi.de/temp/clr/Polygontest.java
http://schabi.de/temp/clr/Program_LowLat.cs

"A patched buffer overflow doesn't mean that there's one less way
attackers can get into your system; it means that your design process
was so lousy that it permitted buffer overflows, and there are probably
thousands more lurking in your code." - Bruce Schneier
 

Lesen sie die antworten

#1 Markus Schaber
04/05/2009 - 18:34 | Warnen spam
Hallo,

Markus Schaber schrieb:

Allerdings hab ich dann festgestellt, dass die selbe C#-.Exe unter
Windows in der Mono Runtime um ca. Faktor 300 schneller làuft, als in
der Microsoft Runtime, und damit zumindest in dieselbe Größenordnung
kommt, wie die Java Implementierung.



Ich hab das inzwischen noch unter Vista64 auf einer Core2Quad Maschine
verifiziert, die Zeiten bewegen sich in àhnlichen Größenordnungen.

Ein All-in-One Projekt zum testen findet sich unter
http://schabi.de/temp/clr/AllInOneSolution.7z

Ich werd mich jetzt auch mal an
microsoft.public.dotnet.framework.performance wenden, vielleicht wissen
die was.

Gruss,
Markus

"A patched buffer overflow doesn't mean that there's one less way
attackers can get into your system; it means that your design process
was so lousy that it permitted buffer overflows, and there are probably
thousands more lurking in your code." - Bruce Schneier

Ähnliche fragen