AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi Performance Vergleich zu C#

Ein Thema von 4dk2 · begonnen am 22. Nov 2019 · letzter Beitrag vom 5. Dez 2019
Antwort Antwort
4dk2

Registriert seit: 4. Sep 2007
176 Beiträge
 
#1

Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 08:39
Delphi-Version: 10.1 Berlin
Moin zusammen,
Hauptsächlich programmier ich zwar nur noch mit C#,
Aber weil ich dort wegen nem Performance-Problem, einige Basic Tests gemacht habe,
hat mich auch interessiert, wie die Performance im Vergleich zu Delphi aussieht.
Und es hat mich doch sehr verwundert

Vorne Weg:
Für den Test bei C# hab ich die neueste(last patch) VS2019 Ide genommen,
Target App: Standard 4.7.2, Konsole, x86, Release (kein debugging...)
(Zeit messen per Stopwatch)

Für den Test unter Delphi:
XE10.1(Berlin) Konsole, X86, Kein Debugging, Optimierung Aktiv
(Zeit messen per JclCounter)

Zusatzttest:
Auch unter Delphi7 gemacht.


Der Test der mich interessiert hat, ist anfür sich recht simple:

Delphi-Quellcode:
// JCL_DEBUG_EXPERT_GENERATEJDBG OFF
// JCL_DEBUG_EXPERT_INSERTJDBG OFF
// JCL_DEBUG_EXPERT_DELETEMAPFILE OFF
program BenchmarkCallSpeed;

{$APPTYPE CONSOLE}

{$R *.res}

uses

  System.SysUtils, JclCounter;

var
  s:string;
  tc:TJclCounter;
  i:integer;
  itotal:integer;
  x:integer;
  totalSecs:double;
  const Iterations=1000000000;
  const TestTarget=100;

function foo(x:integer):integer;
begin
  result:=x*3;
end;

function fooInline(x:integer):integer;inline;
begin
  result:=x*3;
end;

begin
  try
    totalSecs:=0;

    tc:=TJclCounter.Create(true);
    Writeln('Start');
    for itotal := 1 to TestTarget do
    begin
      x:=3;

      tc.Stop;
      tc.Start;
      for i := 0 to Iterations-1 do
      begin
        x:=foo(x);
        //x:=fooInline(x);
      end;
      tc.Stop;
      totalSecs:=totalSecs+tc.ElapsedTime;
      Writeln('Step: '+itotal.ToString()+' = '+tc.ElapsedTime.ToString()+ ' sec X: '+IntToStr(x));
    end;
    Writeln('TOTAL~: '+(totalSecs/TestTarget).ToString());

    tc.Free;

    Writeln('ENDE');
    Readln(s);


  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Ich glaub das ganze ist ja so simpel, dass es jeder verstehen sollte
Ergebnis ist jetzt folgendes:


EDIT!!!!! Die Zeiten angepasst, nachdem X auch noch benutzt wird!

DELPHI XE10.1:
100 Tests
Durchschnitt : 2,360 sekunden
CPU auslastung : 35%~

DELPHI 7:
100 Tests
Durchschnitt : (neuer kommt noch) sekunden
CPU auslastung : 35%~

C#
100 Tests
Durchschnitt : 0,7227 sekunden
CPU auslastung : 35-50%~

C# .Net Core 3.0
100 Tests :
Durchschnitt : (neuer kommt noch) sekunden
CPU auslastung : 35-50%~




Ich finde das extrem krass!
Ich hätte ja gesagt, wegen JIT Code vs Native, wäre da Delphi wahrscheinlich schneller, bzw gleichauf.
aber 4x langsamer?
Was meint ihr dazu?


EDIT:
Falls es jemand selber mit C# vergleichen will...
Wichtig ist aber! Auf Release Testen! das macht nen gewaltigen Unterschied aus.
Code:
public static int Foo(int x)
        {
            return x * 3;
        }

        static void Main(string[] args)
        {

            //Dauertest von Normal

            const int Iterations = 1000000000;
            int x = 0;
            int testtarget = 100;
            double timeges = 0;
            System.Diagnostics.Stopwatch sw;

            Console.WriteLine($"Start:");
            Console.WriteLine($"init: {Foo(3)}"); //JIT init, erste ergebnis sonst evtl verfälscht

            for (int itotal = 1; itotal <= testtarget; itotal++)
            {
                x = 3;
                sw = System.Diagnostics.Stopwatch.StartNew();
                for (int i = 0; i < Iterations; i++)
                {
                    x = Foo(x);
                }
                sw.Stop();
                timeges = timeges + sw.ElapsedMilliseconds;
                Console.WriteLine($"Step: {itotal} = {sw.ElapsedMilliseconds/1000d} X: {x}" );
            }
            Console.WriteLine($"TOTAL: {timeges / testtarget/1000d} ms~");

        }
Edits:
-.Net Core 3.0 hinzugefügt
-Stevie hat darauf hingewiesen, das ja wegen optimierung, die X variable wenigstens 1x benutzt werden muss, daher angepasst, fürs archiv XD

Geändert von 4dk2 (22. Nov 2019 um 10:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.034 Beiträge
 
Delphi 12 Athens
 
#2

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:00
Ändere mal die Deklaration der Funktion auf inline:

function foo(x:integer):integer; inline;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
4dk2

Registriert seit: 4. Sep 2007
176 Beiträge
 
#3

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:08
hmmm, okaay, dann ist delphi gleichauf:

DELPHI XE10.1 (inline):
100 Tests
Durchschnitt : 0,3567 sekunden
CPU auslastung : 35%~
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:14
hmmm, okaay, dann ist delphi gleichauf:
Oft sind es die kleinen Dinge.
Auch eine const-Angabe hilft teilweise.
Oder in diesem Fall ein var-Übergabe damit gar (fast) keine zusätzlichen Variablen/Stack/.... benötigt werden.

Hate "damals" zu D6 Zeiten unsere Anwendung Unicode-Enabled.
Eine ergänzung von const an allen String-Übergabeparametern hatte hier schon auch ind der kompletten Anwendung merklich Geschwindigkeit gebracht.

Für Sowas empfiehlt sich immer eine Performance-Analyse mit AQTime um die relevanten stellen gleich zu finden.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
4dk2

Registriert seit: 4. Sep 2007
176 Beiträge
 
#5

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:27
hmmm, okaay, dann ist delphi gleichauf:
...
Oder in diesem Fall ein var-Übergabe damit gar (fast) keine zusätzlichen Variablen/Stack/.... benötigt werden.
Delphi-Quellcode:
procedure fooVar(var x:integer);//inline;
begin
  x:=x*3;
end;

procedure fooOut(x:integer;out xout:integer);//inline;
begin
  xout:=x*3;
end;
falls du das so meintest, mit und ohne inline, sind die langsam, langsamer als die normale ohne inline (2,1 sek)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.012 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:55
Halt stop!

Wenn du Foo inline markierst, wird der Code schneller, weil er nix mehr ausführt (siehe H2077 in den Compilermeldungen) außer einer leeren Schleife. Es wird nix mit x gemacht also spart er sich auch die Multiplikation. Ein beherztes Writeln(x) nach der Schleife und der code ist wieder langsam. Das liegt einfach daran, dass der Delphi Compiler schrottigen Code erzeugt und Register nicht optimal nutzt.

Aus dem geinlinetem x:=Foo(x) Aufruf wird folgendes:

Delphi-Quellcode:
Project351.dpr.38: x:=foo(x);
004EE8DD 8B155C944F00 mov edx,[$004f945c]
004EE8E3 8D1452 lea edx,[edx+edx*2]
004EE8E6 89155C944F00 mov [$004f945c],edx
Die Variable wird also nicht einfach im Register gehalten sondern unnötigerweise immer zurück geschrieben und gelesen. Den Code und die globalen Variablen in eine Routine zu verlagern hilft übrigens auch nicht. Die Multiplikation direkt durchzuführen hat übrigens denselben ungünstigen Assembly Code zum Ergebnis.

Edit: Wenn Writeln(x) direkt vor oder nach dem sw.Stop steht, dann ist der Assembly Code optimal, denn dann kann x im Register gehalten werden.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (22. Nov 2019 um 10:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.034 Beiträge
 
Delphi 12 Athens
 
#7

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 10:12
Ein beherztes Writeln(x) nach der Schleife und der code ist wieder langsam.
Nicht in 10.3.3 Rio. Da liegen die Werte mit und ohne Writeln(x) annähernd gleichauf.

Übrigens bekomme ich ähnliche Werte, wenn ich den Schleifenbody komplett auskommentiere

Delphi-Quellcode:
program BenchmarkCallSpeed;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Diagnostics;

function foo(x:integer):integer; inline;
begin
  result:=x*3;
end;

const
  Iterations=1000000000;
  TestTarget=100;

var
  s:string;
  tc:TStopwatch;
  i:integer;
  itotal:integer;
  x:integer;
  totalMSecs:Int64;
begin
  try
    totalMSecs:=0;

    tc:=TStopwatch.Create.Create;
    Writeln('Start');
    for itotal := 1 to TestTarget do
    begin
      x:=3;

      tc.Reset;
      tc.Start;
      for i := 0 to Iterations-1 do
      begin
        x:=foo(x);
      end;
      tc.Stop;
      totalMSecs := totalMSecs + tc.ElapsedMilliseconds;
      Writeln(x);
      Writeln('Step: '+itotal.ToString()+' = '+tc.ElapsedMilliseconds.ToString()+ ' ms');
    end;
    Writeln('TOTAL~: '+(totalMSecs/TestTarget).ToString());

    Writeln('ENDE');
    Readln(s);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:02
Mach mal deine funktion inline.

Solche sehr einfachen Tests sind immer mit Vorsicht zu genießen.
I.d.R. sind alle modernen Umgebungen im Alltag gleich schell, da oft eher das "drumherum" wie Framework (VCL gegen - Was ist gerade bei C#/.NET "das Hippe Ding" oder
die Implementierungsalgortihmen der relevantere Teil sind.


Bei C# könnte die "numbercrunshing" Compileroptimierungen für moderne Prozessoren hier eingiges Ausmachen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
4dk2

Registriert seit: 4. Sep 2007
176 Beiträge
 
#9

AW: Delphi Performance Vergleich zu C#

  Alt 22. Nov 2019, 09:22
I.d.R. sind alle modernen Umgebungen im Alltag gleich schell, da oft eher das "drumherum" wie Framework (VCL gegen - Was ist gerade bei C#/.NET "das Hippe Ding" oder
die Implementierungsalgortihmen der relevantere Teil sind.
Eigendlich hat Delphi garnix mit meinem Problem zu tun gehabt.
Es ging darum, dass ich Performance Probleme bei Interfaced aufrufen hatte.
Deswegen hab ich unter C# Normal/Interfaced/Delegate/Events verglichen...
Delphi war dann Just4Fun

Bei C# könnte die "numbercrunshing" Compileroptimierungen für moderne Prozessoren hier eingiges Ausmachen.
Hab mal danach gesucht, aber nix gefunden?
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
532 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: Delphi Performance Vergleich zu C#

  Alt 29. Nov 2019, 16:46
Seit wann war außer Ctrl + F9 Delphi schneller als 3 bis 5 Minuten Compilierung in einer C/C++ IDE. Der Executable Code bei entsprechender Optimierung unter Annahme der Knappheit von Ressurcen gut mithalten. Aber schnell von Geil auf Optimieren war nie.

Das spielt viel eher die Auslastung des L2 Cache mit. Berechnungen habe ich früher auch auf die Oracle geschickt und das Ergebnis zurückgeholt. Das war schon immer schneller als im Executable gerechnet. Ok. Zumindest in einem Teil der Fälle.

-

Warum soll ein JIT Compiler langsamer sein?

Fahre mal im ABAP Floating Point Berechnungen (purstes MS C, wenn überhaupt im Unterbau).

Die Sequenz ist am schnellsten und kann losgelöst vom Kompilat optimiert werden. Finde einen geschlossen Ausdruck zu einem Quantor. Sobald du die Beschränkungen kennst hast du in der Regel gewonnen. Die Laufzeitumgebung muss die Wertebelegung kennen.

Aus der DB Welt ein Vergleich. Wenn man einen Execution Plan einer Query anschaut, könnte man glauben man wüsste was passiert. Seit spätestens 2009 ist besser die Statements auf einer Oracle im Betrieb zu tracen. Die macht schon lange nicht mehr was der Entwickler der Query glaubt und was ihm im Execution Plan angezeigt wird. Man kann eigentlich nurmehr die gröbsten Patzer im Vorfeld vermeiden.

Ein Laufzeitsystem basiert auf brutal optimierten Systemprimitiven.

Einen statischen Compiler nimmt man dann wenn man 100%ig sicher sein will, dass die Ressourcen im Sinne des eigenen Programms verwendet werden und nicht anders. Bei C/C++ Compilern gestaltet sich das dann so, dass bei einer Dissassembly wenig am vermuteten Platz findest.

--

An sich ist in einer (klassischen) prozeduralen Programmiersprache vorzüglich geschlossene Formen zu verwenden (Formeln abzuleiten). Inhalte von Prozeduren sollten komplexer Natur sein und der Ablauf tunlichst starr und im Rahmen vom im Programm definierten explizit definierten Begrenzungen laufen.

Ansonsten musst/kannst du etwas anderes nehmen. Früher als die Compiler aufkamen wurden diese Beschränkung als Segen empfunden, aber mit den Jahrzehnten hat sich das gewandelt. Sinn war die Abbruchstelle genau zu identifizieren. Bei frühen OSen auf einem host ist das Assembler Programm einfach mal mit einem Dumpf geflogen und was das OS (im PC Slang die Anwendung die eigentlich ein ganzer Host Computer im Single User Mode ist) so machte, ...

Die isolierte Runtime welche mit dem OS (Rechenzentrum) die Ressourcen verhandelt liegt auf der Hand.

C#/.net ist in Relation zu anderen Alternativen auch schon auf höchst flexiblem Unternbau mit der Kirche ums Kreuz gelaufen.

Wenn man hingegen bspw. eine Funktion im math. Sinne schreibt, dann können prozedurale Sprachen wieder mithalten. Öffne einen Stream und behandle jeden Wert einzeln. Es handelt sich im Gegensatz zum 'verbreiteten' Wissen um ein wohldefiniertes mathematisches Konstrukt und nicht eine 'hyper' anmutende Form Files einzulesen.

Es macht keinen Sinn mit Bezug auf Prozeduren und Methoden die 'eine' Stelle zu suchen. Eine Objekt ist schon ein instantiiertes Modul. Bei der Vererbung wird genau das eine 'gedanklich' gelandene Modul gesucht und in prozeduralen Sprachen als C gab es nur Files und keine Module usw... Die Notlösung ist inline.

Sobald man sich an das so ca. halt werden bis auf C ohne externe I/O alle Programmiersprachen relativ gleich schnell unter der Annahme, dass die Laufzeitumgebung die Performance zulässt.


Moin zusammen,
Hauptsächlich programmier ich zwar nur noch mit C#,
...

Ich finde das extrem krass!
Ich hätte ja gesagt, wegen JIT Code vs Native, wäre da Delphi wahrscheinlich schneller, bzw gleichauf.
aber 4x langsamer?
Was meint ihr dazu?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz