Vor einiger Zeit habe ich von der sogenannten Leibniz-Reihe erfahren. Mit diesem Verfahren kann man Pi errechnen. Und wenn man schon dabei ist einen Benchmark durchführen 🙂
Ich habe den Programmcode in fünf Programmiersprachen umgesetzt (Fehler schließe ich hier nicht aus und ich freue mich über Hinweise) und zwar:
Python:
#!/usr/bin/python3 #Berechne Pi mit der Leibniz-Reihe import time iterations = 1000000 x = 1 pi = 1 start = time.time() for i in range(2, iterations + 2): x = x * -1 pi = pi + (x / (2*i-1)) pi = pi * 4 end = time.time() print('Pi: ' + str(pi)) print('Time taken for ' + str(iterations) + ' Iterations: ' + str((end - start)*1000000) + ' Mikroseconds')
Javascript:
var iterations = 1000000; var x = 1; var pi = 1; var begin=Date.now(); for (i = 2; i < iterations + 2; i++) { x = x * -1; pi = pi + (x / (2*i-1)); } pi = pi * 4; var end= Date.now(); console.log('Pi: ' + pi); console.log('Took ' + ((end-begin)*1000) + ' Microseconds');
PHP:
<?php $iterations = 1000000; $x = 1; $pi = 1; $begin = microtime(true); for ($i = 2; $i < $iterations + 2; $i++) { $x = $x * -1; $pi = $pi + ($x / (2*$i-1)); } $pi = $pi * 4; $end = microtime(true) - $begin; echo('Pi: ' . $pi . "\n"); echo('Took ' . ($end * 1000 * 1000) . ' Microseconds' . "\n"); ?>
C:
#include <stdio.h> #include <sys/time.h> int main() { struct timeval start, end; long secs_used, micros_used; int iterations = 1000000; float x = 1; float pi = 1; gettimeofday(&start, NULL); for (int i = 2; i < iterations + 2; i++) { x = x * -1; pi = pi + (x / (2.0*i-1.0)); } pi = pi * 4; gettimeofday(&end, NULL); secs_used = (end.tv_sec - start.tv_sec); micros_used = ((secs_used*1000000) + end.tv_usec) - (start.tv_usec); printf("Pi: %f\n", pi); printf("micros_used: %ld\n", micros_used); }
C#:
using System; using System.Diagnostics; namespace Leibniz { class Program { static void Main(string[] args) { int iterations = 1000000; double x = 1; double pi = 1; Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 2; i<iterations + 2; i++) { x = x* -1; pi = pi + (x / (2.0*i-1.0)); } pi = pi* 4; stopwatch.Stop(); Console.WriteLine("Pi: " + pi); Console.WriteLine("micros_used: " + stopwatch.ElapsedMilliseconds * 1000); } } }
Und C für Arduino:
void setup() { Serial.begin(9600); } void loop() { unsigned long iterations = 1000000; Serial.println("Start"); float x = 1; float pi = 1; unsigned long starttime = micros(); for (unsigned long i = 2; i < iterations + 2; i++) { x = x * -1; pi = pi + (x / (2.0*i-1.0)); } pi = pi * 4; unsigned long endtime = micros(); Serial.print("Pi: "); Serial.println(pi); Serial.print("Micros used: "); Serial.println(endtime - starttime); }
Und hier gibt es ein paar Messergebnisse zu den obigen Programmcodes:
Python3 auf dem PC | 258213 µsec | 000.250 sec |
Javascript auf dem PC (Node.JS) | 27000 µsec | 000.027 sec |
Javascript auf dem PC (Firefox) | 1637000 µsec | 001.637 sec |
Javascript auf dem PC (Chrome) | 297000 µsec | 000.297 sec |
C auf dem PC | 5371 µsec | 000.005 sec |
Javascript auf dem EspruinoPico | 458677532 µsec | 458.677 sec |
Python auf dem PyBoard | 26000000 µsec | 026.000 sec |
C auf dem Arduino Uno | 57328564 µsec | 057.329 sec |
Python auf dem RasPi 1 | 3251917 µsec | 003.252 sec |
C auf dem RasPi 1 | 83939 µsec | 000.084 sec |
Javascript auf dem RasPi 1 (Node.JS) | 178000 µsec | 000.178 sec |
C# | 3000 µsec | 000.003 sec |
PHP7 CLI | 61338 µsec | 000.061 sec |
PHP7 Browser | 66730 µsec | 000.066 sec |
Das schöne hier dran ist dass man diesen Programmcode so ziemlich in jeder Sprache und auf jeder Hardware durchführen kann.
Selbstverständlich zeigt dieser Test nicht wie schnell die jeweilige Sprache/Hardware tatsächlich ist, sondern nur wie schnell sie mit Float-Berechnungen umgehen kann. Ein massiver Unterschied besteht natürlich wenn die jeweilige Hardware keine extra Floating Point Hardware besitzt (wie z.B. der Arduino Uno).
13 Antworten zu “Performance Vergleich zwischen verschiedenen Programmiersprachen und Systemen?”
Wir lernen: Es gibt keinen Anlass, die schnarchigen Programmiersprachen JavaScript und Python für irgendwas Produktives einzusetzen.
Vertausche mal die Zeilen mit der Ergebnisausgabe für Pi und der Endzeitpunktmessung – die Ausgabe gehört ja nicht zur Rechnung. 😉
Erledigt. Das sind genau die kleinen Fehler bei denen ich hoffte ein zweites Paar Augen würde sie finden.
Danke!
Hast du bei „Firefox“ schon die neuste Version (also Quantum) verwendet? Angeblich soll das doch unglaublich viel schneller geworden sein…
Ja, das war Quantum!
Hallo,
wäre spannend, PHP noch mit in den Vergleich zu nehmen, als direkter Vergleich zwischen den Skriptsprachen
PHP, okay…
Ist mit hinzugefügt!
Wobei hier natürlich alle Vergleiche und Performance Messungen nicht unbedingt immer auf der selben Plattform erstellt wurden – und bei Windows geht der C und PHP Programmcode garnicht erst (es fehlt gettimeofday()), heißt also man sollte schon selber direkt nachmessen wenn man eine bestimmte Plattform vergleichen will!
Hallo,
netter Vergleich. Ich habe das auf meinem Rechner mit gcc und fpc mal nachgestellt, da ist der fpc noch schneller.
Gruß Björn
Could I offer a Pascal version of this code? Using FreePascal 3.3 compiler is almost as fast than C version
{$mode delphi}
program leibniz;
uses
Windows, Messages, SysUtils, Classes, DateUtils;
var
file_contents: String;
t0,t2: Int64;
i,rounds: Integer;
input_file: TextFile;
x,pi: Double;
Frequency: int64;
begin
// Read the file into a string
QueryPerformanceFrequency(Frequency);
AssignFile(input_file,'rounds.txt');
Reset(input_file);
Readln(input_file, file_contents);
CloseFile(input_file);
rounds := StrToInt(file_contents); // convert into an Integer
QueryPerformanceCounter(t0);
x := 1.0;
pi := 1.0;
for i := 2 to rounds + 1 do
begin
x:= x * -1;
pi:= pi + (x / (2.0 * i - 1.0));
end;
pi:= pi * 4;
QueryPerformanceCounter(t2);
Writeln(Format('%.16f',[pi]));
Writeln('time: '+Format('%.3f',[1000*(t2-t0)/Frequency])+' msec');
end.
Could remove reading rounds.txt file and define number of iterations.
{$mode delphi}
program leibniz;
uses
Windows, Messages, SysUtils, Classes, DateUtils;
var
t0,t2: Int64;
i,rounds: Integer;
x,pi: Double;
Frequency: int64;
begin
// Read the file into a string
QueryPerformanceFrequency(Frequency);
rounds := 1000000;
QueryPerformanceCounter(t0);
x := 1.0;
pi := 1.0;
for i := 2 to rounds + 1 do
begin
x:= x * -1;
pi:= pi + (x / (2.0 * i – 1.0));
end;
pi:= pi * 4;
QueryPerformanceCounter(t2);
Writeln(Format(‚%.16f‘,[pi]));
Writeln(‚time: ‚+Format(‚%.3f‘,[1000*(t2-t0)/Frequency])+‘ msec‘);
end.
Thanks a lot 🙂
If you want test a binary, I uploaded an optimized binary in https://pixeldrain.com/u/jMFWXYIO
I ran some tests using the fastest binary that I could compile for my machine (Ryzen 7 1700)..
C -> 0.141ms
C++ -> 0.141ms
pascal -> 0.157ms
python -> 378.7ms
same in java
public static void main(String[] args) {
int iterations = 1000000;
double x = 1;
double pi = 1;
Long s = System.nanoTime();
for (int i = 2; i<iterations + 2; i++) {
x *= -1;
pi += x / (2.0*i-1.0);
}
pi *= 4;
s = System.nanoTime() – s;
double dd = (double)s;
dd /= 1000;
System.out.println("time in mykro " + dd);
System.out.println("pi " + pi);
}
//time in mykro 3928.5
//pi 3.1415936535887745