--Cible ... C, PHP, HHVM, Ruby, Python, PyPy et notre Kinx
PyPy est maintenant disponible, alors je l'ai ajouté. Quel est le résultat? !!
J'ai lu le benchmark dans cet article [PHP8] JIT peut être utilisé avec PHP.
Je compare Mandelbrot avec JIT en PHP8, mais! , C'est celui que notre Kinx peut également bouger avec la méthode native
! C'est un événement dans le but d'essayer une référence à partir du sentiment de.
Faire un article signifie aussi que c'était un ** jeu **. Ou plutôt que prévu. Tu l'as fait!
Au fait, qu'est-ce que Kinx? Veuillez vous référer à ce qui suit.
Divers programmes de référence sont publiés ici (https://gist.github.com/dstogov/12323ad13d3240aee8f1)](https://gist.github.com/dstogov/12323ad13d3240aee8f1), mais ils sont basés sur cela.
Comme l'environnement est différent, le même résultat ne sera pas obtenu, nous allons donc tout mesurer dans plusieurs langues. Les versions des différentes langues ne peuvent pas correspondre exactement à l'article original, mais je vais le mesurer de plus près et le comparer avec l'article original.
Cependant, comme mentionné dans l 'article original, seul PHP est ** triché **. Tout en évitant cela, en pratique, les performances d'E / S interfèrent également avec la mesure, je vais donc supprimer grossièrement la partie de sortie. Cependant (continuant le paradoxe), C passe sans optimisation car sans la sortie, il semble être sur-optimisé et pas un benchmark. Une sorte de handicap. Toujours rapide.
Après le début de l'exécution, le temps d'exécution est mesuré à l'aide du temporisateur préparé dans chaque langue. Donc, j'ai remarqué que cela n'inclut pas le temps d'analyser et de compiler la source. C ne peut pas être aidé.
Ce qui m'a mis mal à l'aise, c'est que ** HHVM est perçu comme lent, mais la sortie finale est rapide **. Plus précisément, le résultat est que HHVM est perceptivement plus lent que PHP, mais les chiffres sont meilleurs que PHP.
Il a été confirmé que les formulaires suivants sont tous émis lors de la sortie. Mon Kinx (natif) a également fonctionné comme prévu.
*
*
*
*
*
***
*****
*****
***
*
*********
*************
***************
*********************
*********************
*******************
*******************
*******************
*******************
***********************
*******************
*******************
*********************
*******************
*******************
*****************
***************
*************
*********
*
***************
***********************
* ************************* *
*****************************
* ******************************* *
*********************************
***********************************
***************************************
*** ***************************************** ***
*************************************************
***********************************************
*********************************************
*********************************************
***********************************************
***********************************************
***************************************************
*************************************************
*************************************************
***************************************************
***************************************************
* *************************************************** *
***** *************************************************** *****
****** *************************************************** ******
******* *************************************************** *******
***********************************************************************
********* *************************************************** *********
****** *************************************************** ******
***** *************************************************** *****
***************************************************
***************************************************
***************************************************
***************************************************
*************************************************
*************************************************
***************************************************
***********************************************
***********************************************
*******************************************
*****************************************
*********************************************
**** ****************** ****************** ****
*** **************** **************** ***
* ************** ************** *
*********** ***********
** ***** ***** **
* * * *
Maintenant, le sujet principal du benchmark. D'abord à partir du code du programme.
C
La version de 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 ressemble à ceci.
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
Version PHP.
$ 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
Version HHVM.
$ hhvm --version
HipHop VM 3.21.0 (rel)
Compiler: 3.21.0+dfsg-2ubuntu2
Repo schema: ebd0a4633a34187463466c1d3bd327c131251849
PHP et HHVM sont le même code source.
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
Version rubis.
$ ruby --version
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
Code source Ruby.
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
Version Python.
$ python --version
Python 2.7.15+
Version de 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]
Code source Python. PyPy est le même.
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)
Version Kinx.
$ kinx -v
kinx version 0.9.2
Cependant, il y avait un bogue dans la version 0.9.2 qui faisait que les constantes const n'étaient pas propagées correctement en natif, donc j'en ai utilisé une partiellement corrigée ... Le commit est terminé.
Code source de la version régulière de Kinx.
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());
Code source Kinx (natif). Si vous connaissez le type à partir du résultat du calcul, vous n'avez pas besoin de l'écrire, vous pouvez donc simplement ajouter : dbl
à l'argument.
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());
Le résultat s'affiche. La moyenne de 10 fois. Réorganiser par ordre de vitesse.
Je suis désolé, il y a eu un problème avec le programme de mesure et j'ai mesuré à nouveau.
Langue | version | Temps de mesure(Secondes,10 fois la moyenne) | time(real),10 fois la moyenne |
---|---|---|---|
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 |
Hourra! ** Expérience plus lente que PHP ** Plus rapide que HHVM. De plus, je suis tout simplement content parce que la version régulière était ** aussi rapide que la VM Ruby que je pensais rapide **.
Ou plutôt, ** PyPy est exceptionnellement rapide **. J'ai senti une différence. Génial.
La lenteur perçue de HHVM est également indiquée dans le tableau. Le temps de compilation est probablement long. C'est inévitable en raison des spécifications linguistiques. Kinx (natif) voit également une pénalité pour le temps de compilation.
Maintenant, comparons-le avec le résultat de Article original. Dans ce benchmark, la sortie est également supprimée, mais il y a une grande différence dans l'environnement. Je pensais que les tendances rationnelles étaient similaires ... mais seul HHVM est étrange. Il devrait être JIT activé par défaut, alors comparez-le avec JIT activé. Au contraire, le résultat de la version JIT off de l'article original est trop lent et je ne suis pas sûr de ce qui est correct. D'autres sont généralement environ deux fois plus rapides sur le plan environnemental ** qu'aujourd'hui.
Langue | version | Temps de mesure(Secondes,10 fois la moyenne) | Résultat de l'article original | Version originale de l'article |
---|---|---|---|---|
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 |
Le banc est amusant, quand c'est un jeu. «Native» est difficile à trouver, mais c'est l'une des caractéristiques (individualité) de Kinx, donc je veux en prendre bien soin. Faisons de notre mieux.
À la prochaine.
P.S. Au fait, c'est le script utilisé pour la mesure. J'ai essayé d'utiliser le [Process] récemment implémenté (https://qiita.com/Kray-G/items/e44c39ddb2e17659a0a4). Les nombres ci-dessus sont les nombres qui apparaissent dans «moyenne».
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