Manlio Perillo ha scritto:
Guarda che come performance assolute Python non è meglio di PHP.
Tempo fa qualcuno ha fatto dei semplici test.

Occhio alla parola "semplici".
In realtà un test per avere significato deve essere su una applicazione
significativa.
vista questa risposta, mi son messo giù a fare un bench molto semplice.

il bench non fa altro che creare una stringa lunga, scriverla su un file, rileggerla dal file, parsarla con una regexp, splittarla o lavorarla per un numero preassegnato di volte.

Queste operazioni sono quasi la routine per tanti sistemi fw in php basati su template engines, la scrittura di tutto ad esempio è una peculiarità di MovableType. Python su psp sfrutterebbe direttamente il C per parsare il file ed assegnare i valori come template engine, quindi mi è sembrato inutile paragonarli per caratteristiche, ho preferito paragonarli per similitudini.

Non ho testato un db perchè credo che i wrapper siano molto simili (sqlite, mysql, postgre) e la differenza la fa più il db che il linguaggio stesso (anche se la manipolazione gestione dei risultati potrebbe sicuramente dare qualche spunto in più per le conclusioni sul confronto)

Il test è stato fatto sullo stesso PC (centrino 1.6 con hd lento da 5.400 rpm, 1Gb di RAM) con lo stesso Apache (2.0 che php in 2.2 ancora non gira o comunque ha diversi problemi)

Pagina bench.psp
<%
import time, re

# test "char by char" [python emula il tst in php ed è costretto a sfruttare una stringa e una lista]
def bench1(times, path):
   benchtime = getTime(None)
   b = 0
   tmp = ''
   tmpl = []
   for a in range(0, times):
       tmp = readWriteBench(path)
   b = len(tmp)
   for a in range(0, b):
       tmpl.append(tmp[a])
       tmpl[a] = ' '
   tmp = ''.join(tmpl).strip()
   return str(getTime(benchtime))

# test identico [python e php fanno esattamente le stesse cose ma python ha una funzione in più da gestire, la file_get_contents]
def bench2(times, path):
   benchtime = getTime(None)
   a = 0
   b = 0
   tmp = []
   while a < times:
       tmp = readWriteBench(path).split("\r\n")
       a = a + 1
   a = 0
   b = len(tmp)
   while a < b:
       tmp[a] = ' '
       a = a + 1
   tmp.append(''.join(tmp).strip())
   return str(getTime(benchtime))

# test pitoniano [python come l'avrei scritto per fare il secondo test]
def bench3(times, path):
   benchtime = getTime(None)
   tmp = []
   for a in range(0, times):
       tmp = readWriteBench(path).split("\r\n")
   for a in range(0, len(tmp)):
       tmp[a] = ' '
   tmp.append(''.join(tmp).strip())
   return str(getTime(benchtime))

# funzione analoga
def getTime(startTime):
   newtime = time.clock()
   if startTime != None:
       newtime = newtime - startTime
   return newtime

# funzione python, in core in php
def file_get_contents(fileName):
   fp = file(fileName, 'r')
   source = fp.read()
   fp.close()
   return source

# funzione analoga
def readWriteBench(path):
   writeBench(path)
return re.sub("__([0-9]+)__\r\n", "\\1", file_get_contents(path + '/test.py.txt'))

# funzione analoga
def writeBench(path):
   astr = []
   for a in range(0, 10000):
       astr.append("__%i__\r\n" % a)
   fp = file(path + '/test.py.txt', 'w')
   fp.write(''.join(astr))
   fp.close()

# path del file (http://localhost/python/)
path = os.path.abspath('./htdocs/python/')

times = 20 # 50, 100 per differenza più consistente
req.write(bench1(times, path))
req.write("<hr />")
req.write(bench2(times, path))
req.write("<hr />")
req.write(bench3(times, path))
%>


Pagina bench.php
<?php

# test char by char [in php le stringhe sono virtualmente mutabili]
function bench1($times) {
   $benchtime = getTime(null);
   $str = '';
   for($a = 0; $a < $times; $a++)
       $str = readWriteBench();
   for($a = 0, $b = strlen($str); $a < $b; $a++)
       $str{$a} = ' '; # unico punto dove PHP fa la differenza
   $str = trim($str);
   return getTime($benchtime);
}

# test identico
function bench2($times) {
   $benchtime = getTime(null);
   $a = 0;
   $b = 0;
   $tmp = array();
   while($a < $times) {
       $tmp = explode("\r\n", readWriteBench());
       $a = $a + 1;
   }
   $a = 0;
   $b = count($tmp);
   while($a < $b) {
       $tmp[$a] = ' ';
       $a = $a + 1;
   }
   array_push($tmp, trim(implode('', $tmp)));
   return getTime($benchtime);
}

# test piaccaparo [come avrei scritto il secondo test per php]
function bench3($times) {
   $benchtime = getTime(null);
   $tmp = array();
   for($a = 0; $a < $times; $a++)
       $tmp = explode("\r\n", readWriteBench());
   for($a = 0, $b = count($tmp); $a < $b; $a++)
       $tmp[$a] = ' ';
   array_push($tmp, trim(implode('', $tmp)));
   return getTime($benchtime);
}

# funzione analoga
function getTime($startTime) {
   list($a, $b) = explode(' ', microtime());
   $newtime = (float)$a + (float)$b;
   if($startTime !== null)
       $newtime -= $startTime;
   return $newtime;
}

# funzione analoga
function readWriteBench() {
   writeBench();
return preg_replace("/__([0-9]+)__\r\n/", "\\1", file_get_contents('test.php.txt'));
}

# funzione analoga
function writeBench() {
   $astr = array();
   for($a = 0; $a < 10000; $a++)
       array_push($astr, "__{$a}__\r\n");
   $fp = fopen('test.php.txt', 'w');
   fwrite($fp, implode('', $astr));
   fclose($fp);
}

$times = 20; # 50, 100 per differenza più consistente
echo bench1($times);
echo '<hr />';
echo bench2($times);
echo '<hr />';
echo bench3($times);
?>

Magari non sarà il migliore dei tests .. di fatto i risultati sono stati:
1 - picco di quasi 7 mega di ram rubati dal PHP durante il test contro i quasi 200Kb presi in prestito dal python 2 - mezzo secondo di differenza, tendente all' uno con 50 interazioni, 2 quasi e mezzo con 100 interazioni a vantaggio di python

Probabilmente non ho configurato nemmeno benissimo mod_python perchè sebbene vada tutto, nel server mi ritrovo un CGI come configurazione (forse perchè comunque sfrutta l'installazione di python)


A voi commenti, consigli per altri bench o conclusioni :-)

Andrea Giammarchi



P.S. per quel che mi riguarda, che python risultasse più veloce anche in manipolazione consistente di stringhe, l'ho scoperto poco tempo fa con la SourceMap (http://www.phpclasses.org/browse/package/3279.html - c'è anche la versione Python)
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a