PyPy ist jetzt verfügbar, also habe ich es hinzugefügt. Wie ist das Ergebnis? !!
Ich habe den Benchmark in diesem Artikel gelesen. [PHP8] JIT kann mit PHP verwendet werden.
Ich vergleiche Mandelbrot mit JIT in PHP8, aber! Dies ist die, die unser Kinx auch mit der "nativen" Methode unterstützen kann! Es ist eine Veranstaltung mit dem Ziel, einen Benchmark aus dem Gefühl von auszuprobieren.
Einen Artikel zu machen bedeutet auch, dass es ein ** Spiel ** war. Oder eher als erwartet. Du hast es geschafft!
Was ist übrigens Kinx? Bitte beachten Sie Folgendes.
Verschiedene Benchmark-Programme werden hier veröffentlicht (https://gist.github.com/dstogov/12323ad13d3240aee8f1)](https://gist.github.com/dstogov/12323ad13d3240aee8f1), aber sie basieren darauf.
Da die Umgebung unterschiedlich ist, wird nicht das gleiche Ergebnis erzielt, sodass wir alle in mehreren Sprachen messen. Die Versionen der verschiedenen Sprachen konnten nicht genau auf den Originalartikel abgestimmt werden, aber ich werde es genauer messen und mit dem Originalartikel vergleichen.
Wie im Originalartikel erwähnt, wird jedoch nur PHP ** betrogen **. Obwohl dies praktisch vermieden wird, beeinträchtigt die E / A-Leistung auch die Messung, sodass ich den Ausgabeteil grob löschen werde. (Fortsetzung des Paradoxons) C geht jedoch ohne Optimierung, da es ohne die Ausgabe überoptimiert zu sein scheint und kein Benchmark ist. Eine Art Handicap. Immer noch schnell.
Nach dem Start der Ausführung wird die Ausführungszeit mit dem in jeder Sprache vorbereiteten Timer gemessen. Daher habe ich festgestellt, dass die Zeit zum Parsen und Kompilieren der Quelle nicht enthalten ist. C kann nicht geholfen werden.
Was mich unwohl gefühlt hat, ist, dass ** HHVM als langsam empfunden wird, aber die endgültige Ausgabe schnell ist **. Insbesondere ist das Ergebnis, dass HHVM wahrnehmungsmäßig langsamer als PHP ist, die Zahlen jedoch besser als PHP sind.
Es wurde bestätigt, dass die folgenden Formulare alle ausgegeben werden, wenn die Ausgabe ausgeführt wird. Mein Kinx (native) hat auch wie erwartet funktioniert.
*
*
*
*
*
***
*****
*****
***
*
*********
*************
***************
*********************
*********************
*******************
*******************
*******************
*******************
***********************
*******************
*******************
*********************
*******************
*******************
*****************
***************
*************
*********
*
***************
***********************
* ************************* *
*****************************
* ******************************* *
*********************************
***********************************
***************************************
*** ***************************************** ***
*************************************************
***********************************************
*********************************************
*********************************************
***********************************************
***********************************************
***************************************************
*************************************************
*************************************************
***************************************************
***************************************************
* *************************************************** *
***** *************************************************** *****
****** *************************************************** ******
******* *************************************************** *******
***********************************************************************
********* *************************************************** *********
****** *************************************************** ******
***** *************************************************** *****
***************************************************
***************************************************
***************************************************
***************************************************
*************************************************
*************************************************
***************************************************
***********************************************
***********************************************
*******************************************
*****************************************
*********************************************
**** ****************** ****************** ****
*** **************** **************** ***
* ************** ************** *
*********** ***********
** ***** ***** **
* * * *
Nun zum Hauptthema der Benchmark. Zuerst aus dem Programmcode.
C
Die Version von gcc.
$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
C sieht so aus.
mandelbrot.c
#include <stdio.h>
#include <sys/time.h>
#define BAILOUT 16
#define MAX_ITERATIONS 1000
int mandelbrot(double x, double y)
{
double cr = y - 0.5;
double ci = x;
double zi = 0.0;
double zr = 0.0;
int i = 0;
while(1) {
i ++;
double temp = zr * zi;
double zr2 = zr * zr;
double zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}
int main (int argc, const char * argv[]) {
struct timeval aTv;
gettimeofday(&aTv, NULL);
long init_time = aTv.tv_sec;
long init_usec = aTv.tv_usec;
int x,y;
for (y = -39; y < 39; y++) {
//printf("\n");
for (x = -39; x < 39; x++) {
volatile int i = mandelbrot(x/40.0, y/40.0);
//if (i==0)
// printf("*");
//else
// printf(" ");
}
}
//printf ("\n");
gettimeofday(&aTv,NULL);
double query_time = (aTv.tv_sec - init_time) + (double)(aTv.tv_usec - init_usec)/1000000.0;
printf ("C Elapsed %0.3f\n", query_time);
return 0;
}
PHP/HHVM
PHP-Version.
$ php --version
PHP 7.2.24-0ubuntu0.18.04.6 (cli) (built: May 26 2020 13:09:11) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.24-0ubuntu0.18.04.6, Copyright (c) 1999-2018, by Zend Technologies
HHVM-Version.
$ hhvm --version
HipHop VM 3.21.0 (rel)
Compiler: 3.21.0+dfsg-2ubuntu2
Repo schema: ebd0a4633a34187463466c1d3bd327c131251849
PHP und HHVM sind der gleiche Quellcode.
mandelbrot.php
<?php
define("BAILOUT",16);
define("MAX_ITERATIONS",1000);
class Mandelbrot
{
function Mandelbrot()
{
$d1 = microtime(1);
for ($y = -39; $y < 39; $y++) {
for ($x = -39; $x < 39; $x++) {
$this->iterate($x/40.0,$y/40.0);
}
}
$d2 = microtime(1);
$diff = $d2 - $d1;
printf("PHP Elapsed %0.3f\n", $diff);
}
function iterate($x,$y)
{
$cr = $y-0.5;
$ci = $x;
$zr = 0.0;
$zi = 0.0;
$i = 0;
while (true) {
$i++;
$temp = $zr * $zi;
$zr2 = $zr * $zr;
$zi2 = $zi * $zi;
$zr = $zr2 - $zi2 + $cr;
$zi = $temp + $temp + $ci;
if ($zi2 + $zr2 > BAILOUT)
return $i;
if ($i > MAX_ITERATIONS)
return 0;
}
}
}
$m = new Mandelbrot();
?>
Ruby
Ruby-Version.
$ ruby --version
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
Ruby-Quellcode.
mandelbrot.rb
BAILOUT = 16
MAX_ITERATIONS = 1000
class Mandelbrot
def initialize
#puts "Rendering"
for y in -39...39 do
#puts
for x in -39...39 do
i = iterate(x/40.0,y/40.0)
#if (i == 0)
# print "*"
#else
# print " "
#end
end
end
end
def iterate(x,y)
cr = y-0.5
ci = x
zi = 0.0
zr = 0.0
i = 0
while(1)
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
return i if (zi2 + zr2 > BAILOUT)
return 0 if (i > MAX_ITERATIONS)
end
end
end
time = Time.now
Mandelbrot.new
#puts
puts "Ruby Elapsed %f" % (Time.now - time)
Python/PyPy
Python-Version.
$ python --version
Python 2.7.15+
Version von PyPy.
$ pypy --version
Python 2.7.13 (5.10.0+dfsg-3build2, Feb 06 2018, 18:37:50)
[PyPy 5.10.0 with GCC 7.3.0]
Python-Quellcode. PyPy ist das gleiche.
mandelbrot.py
import sys, time
stdout = sys.stdout
BAILOUT = 16
MAX_ITERATIONS = 1000
class Iterator:
def __init__(self):
#print 'Rendering...'
for y in range(-39, 39):
#stdout.write('\n')
for x in range(-39, 39):
i = self.mandelbrot(x/40.0, y/40.0)
#if i == 0:
#stdout.write('*')
#else:
#stdout.write(' ')
def mandelbrot(self, x, y):
cr = y - 0.5
ci = x
zi = 0.0
zr = 0.0
i = 0
while True:
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
if zi2 + zr2 > BAILOUT:
return i
if i > MAX_ITERATIONS:
return 0
t = time.time()
Iterator()
print 'Python Elapsed %.02f' % (time.time() - t)
Kinx/Kinx(native)
Kinx-Version.
$ kinx -v
kinx version 0.9.2
In der Version 0.9.2 gab es jedoch einen Fehler, dass Konstantenkonstanten in nativ nicht korrekt weitergegeben wurden, sodass ich eine teilweise feste Version verwendete ... Das Commit ist abgeschlossen.
Quellcode der regulären Kinx-Version.
mandelbrot.kx
const BAILOUT = 16;
const MAX_ITERATIONS = 1000;
function mandelbrot(x, y) {
var cr = y - 0.5;
var ci = x;
var zi = 0.0;
var zr = 0.0;
var i = 0;
while (true) {
i++;
var temp = zr * zi;
var zr2 = zr * zr;
var zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}
var tmr = new SystemTimer();
var x,y;
for (y = -39; y < 39; y++) {
#System.print("\n");
for (x = -39; x < 39; x++) {
var i = mandelbrot(x/40.0, y/40.0);
#if (i==0)
# System.print("*");
#else
# System.print(" ");
}
}
#System.print("\n");
System.print("Kinx Elapsed %0.3f\n" % tmr.elapsed());
Kinx (nativer) Quellcode. Wenn Sie den Typ aus dem Berechnungsergebnis kennen, müssen Sie ihn nicht schreiben, sondern können dem Argument einfach : dbl
hinzufügen.
mandelbrotn.kx
const BAILOUT = 16;
const MAX_ITERATIONS = 1000;
native mandelbrot(x:dbl, y:dbl) {
var cr = y - 0.5;
var ci = x;
var zi = 0.0;
var zr = 0.0;
var i = 0;
while (true) {
i++;
var temp = zr * zi;
var zr2 = zr * zr;
var zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}
var tmr = new SystemTimer();
var x,y;
for (y = -39; y < 39; y++) {
#System.print("\n");
for (x = -39; x < 39; x++) {
var i = mandelbrot(x/40.0, y/40.0);
#if (i==0)
# System.print("*");
#else
# System.print(" ");
}
}
#System.print("\n");
System.print("Kinx(native) Elapsed %0.3f\n" % tmr.elapsed());
Das Ergebnis wird angezeigt. Der Durchschnitt von 10 mal. In der Reihenfolge der Geschwindigkeit neu anordnen.
Es tut mir leid, es gab ein Problem mit dem Messprogramm und ich habe erneut gemessen.
Sprache | Ausführung | Messzeit(Sekunden,10 mal durchschnittlich) | time(real),10 mal durchschnittlich |
---|---|---|---|
C | 7.4.0 | 0.018 | 0.046 |
PyPy | 5.10.0 | 0.020 | 0.122 |
Kinx(native) | 0.9.2 | 0.048 | 0.107 |
HHVM | 3.21.0 | 0.068 | 0.552 |
PHP | 7.2.24 | 0.182 | 0.241 |
Ruby | 2.5.1 | 0.365 | 0.492 |
Kinx | 0.9.2 | 0.393 | 0.457 |
Python | 2.7.15 | 0.564 | 0.601 |
Hurra! ** Erfahrung langsamer als PHP ** Schneller als HHVM. Außerdem bin ich einfach glücklich, weil die reguläre Version ** so schnell war wie die Ruby-VM, die ich für schnell hielt **.
Oder besser gesagt, ** PyPy ist ungewöhnlich schnell **. Ich fühlte einen Unterschied. Toll.
Die wahrgenommene Langsamkeit von HHVM ist ebenfalls in der Tabelle gezeigt. Die Kompilierungszeit ist wahrscheinlich lang. Dies ist aufgrund der Sprachspezifikationen unvermeidlich. Kinx (native) sieht auch eine Strafe für die Kompilierungszeit.
Vergleichen wir es nun mit dem Ergebnis von Originalartikel. In diesem Benchmark wird die Ausgabe ebenfalls unterdrückt, es gibt jedoch einen großen Unterschied in der Umgebung. Ich fand die rationalen Trends ähnlich ... aber nur HHVM ist seltsam. Es sollte standardmäßig JIT aktiviert sein, vergleichen Sie es also mit JIT on. Im Gegenteil, das Ergebnis der JIT-Off-Version des Originalartikels ist zu langsam und ich bin mir nicht sicher, was richtig ist. Andere sind in der Regel umweltfreundlich ** etwa doppelt so schnell wie jetzt.
Sprache | Ausführung | Messzeit(Sekunden,10 mal durchschnittlich) | Ergebnis des Originalartikels | Originalartikelversion |
---|---|---|---|---|
C | 7.4.0 | 0.018 | 0.022 | 4.9.2 |
PyPy | 5.10.0 | 0.020 | ||
Kinx(native) | 0.9.2 | 0.048 | ||
HHVM | 3.21.0 | 0.068 | 0.030 | 3.5.0 |
PHP | 7.2.24 | 0.182 | 0.281 | 7 |
Ruby | 2.5.1 | 0.365 | 0.684 | 2.1.5 |
Kinx | 0.9.2 | 0.393 | ||
Python | 2.7.15 | 0.564 | 1.128 | 2.7.8 |
Bänken macht Spaß, wenn es ein Spiel ist. Native
ist schwer zu bekommen, aber dies ist eines der Merkmale (Individualität) von Kinx, deshalb möchte ich mich gut darum kümmern. Geben wir unser Bestes.
Bis zum nächsten Mal.
P.S. Dies ist übrigens das Skript, das für die Messung verwendet wird. Ich habe versucht, den kürzlich implementierten Prozess zu verwenden. Die obigen Zahlen sind die Zahlen, die anstelle von "Durchschnitt" erscheinen.
mandbench.kx
using Process;
var count = 10;
var command = [$$[1], $$[2]];
var r = [];
var re = /[0-9]+\.[0-9]+/;
for (var i = 0; i < count; ++i) {
var result = "";
var [r1, w1] = new Pipe();
var p1 = new Process(command, { out: w1 }).run();
w1.close();
while (p1.isAlive() || r1.peek() > 0) {
var buf = r1.read();
if (buf.length() < 0) {
System.println("Error...");
return 1;
} else if (buf.length() > 0) {
result += buf;
} else {
// System.println("no input...");
}
}
re.reset(result);
if (re.find()) {
r.push(Double.parseDouble(re.group[0].string));
}
}
var total = r.reduce(&(r, e) => r + e);
System.println("total : %8.3f" % total);
System.println("count : %8d" % r.length());
System.println("average: %8.3f" % (total / r.length()));
Recommended Posts