mod_python vs. mod_php

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
perbeatus
Piegowaty Guziec
Piegowaty Guziec
Posty: 3
Rejestracja: 17 lip 2006, 07:58
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME

mod_python vs. mod_php

Post autor: perbeatus »

//============================================================================
UPDATE!

Biorąc sobie do serca uwagę o pominięciu PDO w teście postanowiłem sprawdzić tą bibliotekę w szczególności że jest ona integralną częścią PHP.
Przy okazji sprawdziłem jeszcze jak mają się PEAR i PDO gdy zastosujemy tranzakcję.
Nie bawiłem się już rysunki, więc wyniki w postaci liczbowej.

PDO SELECT 500tys rekordów: 3.25s
PDO INSERT 500tys rekordów bez transakcji: 2.86m
PDO INSERT 500tys rekordów z tranzakcjami: 25.8s

PEAR INSERT 500tys rekordów z tranzakcjami: po 15m odchciało mi się czekać :>


Jak widać uwaga jaką poczynił Dawidgarus była zupełnie słuszna. PDO jest najlepszy pod każdym wzgęldem.


//============================================================================


Witam.

Ostatnio nie było u mnie w pracy kierownika i mogłem zająć się duperelami, więc postanowiłem porównać wydajność PHP względem Python'a w aplikacjach WWW.
W internecie znalazłem opinie jakoby serwisy napisane w oparciu o mod_python były dwukrotnie szybsze niż te napisane w mod_php, ale nie natrafiłem na żadne faktyczne porównanie szybkości wykonywania skryptów.

Opracowałem więc swój własny test sprawdzający to co mnie interesuje najbardziej czyli szybkość pracy z bazą danych.

Test składał się z dwóch części.
Pierwszy polegał na wprowadzeniu 500tys. rekordów do pustej tabeli w bazie danych MySQL.
Drugi na pobraniu wszystkich wprowadzonych wpisów i małego zmodyfikowaniu każdego w kodzie (nie bazie).

Tworząc skrypty do testów postarałem się aby były one jak najbardziej do siebie podobne. Stworzyłem szablon HTML który przy pomocy mechanizmów AJAX wywoływał zadany skrypt i wyświetlał jego wynik. Pomiaru czasu mogłem dzięki temu dokonać za pomocą plugin'u Firebug.

Platforma testowa:

Intel C2D 2.66 GHz
1 GB RAM

Ubuntu 2.6.27-11-generic
apache2 2.2.9-7ubuntu3
mysql 5.0.67-0ubuntu6
libapache2-mod-php5 5.2.6-2ubuntu4.1
libapache2-mod-python 3.3.1-3
python 2.5.2-1ubuntu1
php 5.2.6-2ubuntu4.1 (takie samo php-cli)
firefox 3.0.6-0ubuntu0.8.10.1

Baza:

Kod: Zaznacz cały

CREATE TABLE `zzz_aa_pracownicy` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `imie` varchar(255) collate utf8_polish_ci NOT NULL,
  `nazwisko` varchar(255) collate utf8_polish_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci ROW_FORMAT=COMPACT;
Wspólny HTML:

Kod: Zaznacz cały

<html>
<head>
<script type="text/javascript">
function getName() {
	var c = document.getElementById('cont');
	var xmlHttp;
	try { xmlHttp=new XMLHttpRequest(); } catch(e) { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }
	xmlHttp.open("GET","tu_sciezka_do_skryptu",true);
	xmlHttp.onreadystatechange=function() {
		if(xmlHttp.readyState==4) {
			c.innerHTML = xmlHttp.responseText;
		}
	}
	xmlHttp.send(null);
}
</script>
</head>
<body>

<button onClick="getName()">Dawaj</button>


<div id="cont"></div>

</body>
</html>

//=======================================================

TEST 1: Wprowadzenie do bazy 500 000 rekordów.

PYTHON:

Kod: Zaznacz cały

import MySQLdb;

def index():
	db = MySQLdb.connect(host="localhost", user="user", passwd="passss", db="db");
	cursor = db.cursor();
	for i in range(0, 500000):
		q = "INSERT INTO zzz_aa_pracownicy(imie, nazwisko) VALUES('imie %d', 'nazwisko %d')" % (i, i);
		cursor.execute(q);
	db.commit();
	return "OK";
PHP:

Kod: Zaznacz cały

<?php
$db = mysql_connect("localhost", "user", "passss");
mysql_select_db("db", $db);

for($i = 0; $i < 500000; $i++)
	mysql_query("INSERT INTO zzz_aa_pracownicy(imie, nazwisko) VALUES('imie $i', 'nazwisko $i')", $db);

mysql_close($db);

echo "OK";
?>
PHP_PEAR:

Kod: Zaznacz cały

<?php
$DSN = "mysql://user:passs@localhost/db";

require_once("PEAR/MDB2.php");

$db = MDB2::connect($DSN);

for($i = 0; $i < 50000; $i++)
	$db->query("INSERT INTO zzz_aa_pracownicy(imie, nazwisko) VALUES('imie $i', 'nazwisko $i')");

$db->disconnect();

echo "OK";
?>
WYNIKI:

Każdy skrypt został wykonany 10 a wynik końcowy jest średnią. Po każdym wprowadzeniu danych, były one sprawdzane pod względem poprawności, a następnie kasowane, tak aby za każdym razem skrypt wypełniał pusta tabelę.

Proszę zwrócić uwagę, że PHP_PEAR dodaje tylko 50 000 rekordów. Jest to spowodowane tym, że przy 500 000 po 20min czekania na zakończenie skryptu poddałem się. Nie pomogło powiększanie pamięci ani inne zabiegi.

PYTHON: 50.15s
PHP: 178.20s
PHP_PEAR: 304.20s

Obrazek


//=======================================================


TEST 2: Wczytanie 500 000 rekordów z bazy.

PYTHON:

Kod: Zaznacz cały

import MySQLdb;

def index():
	db = MySQLdb.connect(host="localhost", user="user", passwd="passs", db="db");
	cursor = db.cursor(MySQLdb.cursors.DictCursor);
	cursor.execute("SELECT * FROM zzz_aa_pracownicy");
	pr = [];
	i = 1;
	for i in range(cursor.rowcount):
		r = cursor.fetchone();
		r['imie'] = "%d" % i;
		r['nazwisko'] = "%d" % i;
		pr.append(r);
		i += 1;
	
	ret = "%d" % cursor.rowcount;
	return ret;

PHP:

Kod: Zaznacz cały

<?php
ini_set("memory_limit","300M");
$db = mysql_connect("localhost", "user", "passs");
mysql_select_db("db", $db);

$res = mysql_query("SELECT * FROM zzz_aa_pracownicy", $db);
$num = mysql_num_rows($res);
$pr = array();
for($i = 0; $i < $num; $i++)
{
	$r = mysql_fetch_assoc($res);
	$r["imie"] = $i;
	$r["nazwisko"] = $i;
	$pr[] = $r;
}

mysql_close($db);

echo $num;
?>
PHP_PEAR:

Kod: Zaznacz cały

<?php
ini_set("memory_limit","300M");

$DSN = "mysql://user:passs@localhost/db";

require_once("PEAR/MDB2.php");

$db = MDB2::connect($DSN);

$res = $db->query("SELECT * FROM zzz_aa_pracownicy");
$num = $res->numRows($res);
$pr = array();
for($i = 0; $i < $num; $i++)
{
	$r = $res->fetchRow(MDB2_FETCHMODE_ASSOC);
	$r["imie"] = $i;
	$r["nazwisko"] = $i;
	$pr[] = $r;
}

$db->disconnect();

echo $num;
?>
WYNIKI:

Procedura testowa taka sama.
W przypadku PHP musiałem jawnie zadeklarować ilość przydzielanej pamięci. 300M to troszkę ponad 40MB nadwyżki. Przy 250M program wciąż krzyczał o więcej.
Ponieważ skrypty miały być jak najbardziej podobne nie wykorzystałem w pythonie, oraz PEAR funkcji fetchall(). Przetestowałem jednak jeszcze wersję z tą funkcją i wyniki były na tyle zbliżone że pominąłem ją w teście.

PYTHON: 5.83s
PHP: 3.76s
PHP_PEAR: 10.04s

Obrazek

//=======================================================


Jako ciekawostkę uruchomiłem także skrypty w konsoli aby sprawdzić jak ma się wydajność modułów apacha do wersji konsolowych. Co ciekawe różnice nie były wielkie.

TEST 1 CON:

PYTHON:
matis@matis-desktop:~/public_html/python$ time python insert.py
real 0m50.567s
user 0m19.913s
sys 0m3.076s

PHP:
matis@matis-desktop:~/public_html/python$ time php insert.php
real 2m35.533s
user 0m3.248s
sys 0m3.072s


Mam nadzieję, że porównanie owo się komuś przyda przy wyborze języka skryptowego do jego zastosowań.
Zapraszam do dyskusji. :)

Natomiast adminów i moderatorów proszę o wyrozumiałość co do długości posta :)
17piotrek

Odp: mod_python vs. mod_php

Post autor: 17piotrek »

Zapraszam do dyskusji. :)
No wiec ja pierwszy;) Moim zdaniem, lepiej jednak korzystac z php. Duzo wiecej danych pobiera sie niz wstawia.
Awatar użytkownika
Hauleth
Wytworny Kaczor
Wytworny Kaczor
Posty: 382
Rejestracja: 18 sie 2008, 17:43
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86

Odp: mod_python vs. mod_php

Post autor: Hauleth »

A ja mam inny powód by używać PHP. Praktycznie nie ma serwerów obsługujących Pythona lub Ruby :/
Jeśli problem rozwiązany dodaj na początku tematu [SOLVED].

Biblioteka do C++ - Bust Lib: http://code.google.com/p/bust/
mikolajs
Wytworny Kaczor
Wytworny Kaczor
Posty: 352
Rejestracja: 15 paź 2008, 18:30
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: KDE Plasma

Odp: mod_python vs. mod_php

Post autor: mikolajs »

Czytałem, gdzieś o podobnych testach wydajności i wynikało z nich, że średnio mod_python jest nieco wolniejszy. Natomiast mod WSGI jest już szybszy niż PHP, chociaż nie jest chyba jeszcze do końca dopracowany. Co prawda hosting PHP jest tańszy, ale na google można mieć darmową stronę z pythonem (google app engine).
dawidgarus
Wytworny Kaczor
Wytworny Kaczor
Posty: 418
Rejestracja: 09 lut 2007, 23:17
Płeć: Mężczyzna
Wersja Ubuntu: 9.10
Środowisko graficzne: GNOME
Architektura: x86
Kontakt:

Odp: mod_python vs. mod_php

Post autor: dawidgarus »

szkoda, że nie sprawdziłeś jak prezentuje się wynik php+pdo...
perbeatus
Piegowaty Guziec
Piegowaty Guziec
Posty: 3
Rejestracja: 17 lip 2006, 07:58
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME

Odp: mod_python vs. mod_php

Post autor: perbeatus »

Update postu.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 6 gości