Delphi-Forum.de Delphi-Library.de
C-Sharp-Forum.de C-Sharp-Library.de
Registrieren Login Suche Hilfe Sitemap
Annehmbare Delegate-Performance...
spacer
Autor Nachricht
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

Beiträge: 2965
Erhaltene Danke: 22
Dabei seit: 12.11.2005
Wohnort: Brackenheim

Win 7
F#, C# (VS2010)
BeitragVerfasst: Mo 04.02.08 16:35  Antworten mit Zitat Beitrag melden
Dass Delegates seit 2.0 alles andere als langsam sind, habe ich gehört. Trotzdem wollte ich lieber auf Nummer Sicher gehen, bevor ich meiner TestStopwatch-Klasse eine StressTest-Method verpasse, die einfach n-mal einen Delegate aufruft und die Zeit misst. Die Ergebnisse haben mich nicht bestätigt, sondern eher sprachlos gemacht...
ausblenden volle Höhe C#-Quelltext markieren
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
static void Main(string[] args)
{
  int times = 1000000000;
  float x = 1;

  using (new TestStopwatch("By Hand"))
    for (int i = 0; i < times; i++)
      x *= x;

  TestStopwatch.StressTest("Stress",
    () => x *= x,
    times);

  // und gleich nochmal, um den Jitter und Ähnliches
  // auszuschließen
  using (new TestStopwatch("By Hand"))
    for (int i = 0; i < times; i++)
      x *= x;

  TestStopwatch.StressTest("Stress",
    () => x *= x,
    times);

  // zum Spaß noch hinzugefügt, die Ergebnisse
  // hab ich nicht anders erwartet
  using (new TestStopwatch("Enumerable"))
    foreach (var i in Enumerable.Range(1, times))
      x *= x;

  Console.WriteLine(x);
  Console.ReadLine();
}

ausblenden Quelltext markieren
1:
2:
3:
4:
5:
By Hand: 5074 ms
Stress: 4954 ms
By Hand: 5067 ms
Stress: 4955 ms
Enumerable: 8876 ms


Im Anhang noch das gesamte Projekt, da ich nicht erwarte, dass ihr mir das Ergebnis abkauft :nut: .

PS: Delphi ist noch einmal 10% langsamer :mrgreen: .
Einloggen, um Attachments anzusehen!
Private Nachricht sendenPosting in privater Nachricht zitieren
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic star
Chefentwickler

Beiträge: 17543
Erhaltene Danke: 105
Dabei seit: 07.07.2002
Wohnort: Server-Souterrain

Win 7
Delphi Prism, C# (VS 2010)
BeitragVerfasst: Mo 04.02.08 16:47  Antworten mit Zitat Beitrag melden
Bei mir sind die Delegates zwar nicht schneller, aber auch nur unwesentlich (wahrscheinlich im Bereich der Messgenauigkeit) langsamer:
ausblenden Quelltext markieren
1:
2:
3:
4:
5:
By Hand: 10786 ms
Stress: 10818 ms
By Hand: 10606 ms
Stress: 10804 ms
Enumerable: 26184 ms

Auf jeden Fall mal ein interessanter Test! :zustimm: Insbesondere in Multithreaded-Anwendungen braucht man Delegates ja ständig, um sie an Invoke zu übergeben :-)

_________________
I am of peace. Always.
Vom 9.9. bis 13.9. in Urlaub
Private Nachricht sendenPosting in privater Nachricht zitieren Webseite dieses Mitglieds besuchen
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 2965
Erhaltene Danke: 22
Dabei seit: 12.11.2005
Wohnort: Brackenheim

Win 7
F#, C# (VS2010)
BeitragVerfasst: Mo 04.02.08 20:22  Antworten mit Zitat Beitrag melden
Oh lala, bin sogar mit angezogener Handbremse gefahren: Platform Target war zum Testen auf x86 gestellt.
ausblenden C#-Quelltext markieren
1:
2:
3:
4:
By Hand: 4358 ms
Stress: 4072 ms
By Hand: 4295 ms
Stress: 4057 ms

Dynamischer Code ist demnach 5% schneller als statischer :lol: . Auf einem anderen Rechner komme ich auf etwa den gleichen Wert - außer natürlich unter Mono ;) .
Der Asm-Code würde mich einmal interessieren, aber a) wüsste ich spontan nicht, wie man an ihn herankommt (über VS kann es ja nur mit angehängtem Debugger funktionieren) und b) würde ich mit dem Ergebnis sowieso nichts anfangen können :mrgreen: .
Private Nachricht sendenPosting in privater Nachricht zitieren
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star

Beiträge: 415
Dabei seit: 06.02.2004
Wohnort: München


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Mo 04.02.08 21:11  Antworten mit Zitat Beitrag melden
Khabarakh hat folgendes geschrieben:
Dynamischer Code ist demnach 5% schneller als statischer :lol:
Ist nicht dynamischer Code. Ist nur ein Zeiger auf den Code.
Delegates sind dann schneller, wenn sie auf virtuelle Methoden zeigen.
Denn beim zuweisen wird der virtual dispatch nur einmal ausgeführt und dann immer direkt die richtige Implementierung aufgerufen.
Das ist der gleiche Effekt wie bei Interfaces.

Aber: Delegates verhindern JIT-Optimierungen, und damit meine ich Inlining, da der JITter für andere Optimierungen zu dumm ist.
Private Nachricht sendenPosting in privater Nachricht zitieren
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 2965
Erhaltene Danke: 22
Dabei seit: 12.11.2005
Wohnort: Brackenheim

Win 7
F#, C# (VS2010)
BeitragVerfasst: Mo 04.02.08 23:24  Antworten mit Zitat Beitrag melden
Aber auch das ist doch kein Grund, dass sie schneller als inline Code sind, oder :gruebel: ? Es kann doch eigentlich nur so sein, dass der assemblierte hunz normale Code auf irgendeine Art nicht optimal ist.
Private Nachricht sendenPosting in privater Nachricht zitieren
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star

Beiträge: 415
Dabei seit: 06.02.2004
Wohnort: München


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Di 05.02.08 01:32  Antworten mit Zitat Beitrag melden
Khabarakh hat folgendes geschrieben:
Aber auch das ist doch kein Grund, dass sie schneller als inline Code sind, oder :gruebel: ? Es kann doch eigentlich nur so sein, dass der assemblierte hunz normale Code auf irgendeine Art nicht optimal ist.
Inlining auf Teufel komm raus kann die Anzahl der zu intialisierenden locals brachial erhöhen.
Es kann auch einfach sein, dass die statische Methode hinter dem delegate klein genug ist, so dass der JIT sie gut genug kapiert hat um den loop auszurollen, oder CPU Register nehmen konnte.
Der andere Code war ja innerhalb des Method bodies, die Delegates sind eigene Methoden.
Private Nachricht sendenPosting in privater Nachricht zitieren
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Moderator

(Threadstarter)

Beiträge: 2965
Erhaltene Danke: 22
Dabei seit: 12.11.2005
Wohnort: Brackenheim

Win 7
F#, C# (VS2010)
BeitragVerfasst: Di 05.02.08 22:14  Antworten mit Zitat Beitrag melden
Ich muss mich wohl entschuldigen, mir ist gerade eben erst eingefallen, wie Closures eigentlich implementiert werden :duck: . So sieht das Ganze aus, nachdem jede Schleife ihre eigene x-Variable bekommt (= Die Inline-Loops wirklich lokale Variablen benutzen und nicht die autogenerierten Felder der Lambdas).
ausblenden Quelltext markieren
1:
2:
3:
4:
Inline: 3541 ms
Stress: 4263 ms
Inline: 3527 ms
Stress: 4153 ms

Während der erste Code also ein Inline<=>Delegate-Vergleich war (beide Male ldfld), war das nun eher ein ldloc<=>ldfld-Vergleich. Da man bei anonymen Methoden aber gebundene Variablen kaum vermeiden kann (schon allein, damit sie nicht einfach wegoptimiert werden), wird es wohl meistens auf den zweiten Fall herauslaufen, womit man bei meiner StressTest-Methode immer mit einem Overhead rechnen muss. Schade :( .
Private Nachricht sendenPosting in privater Nachricht zitieren
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
Beiträge vom vorherigen Thema anzeigen:   
home home