Mortal combat: PHP5 vs. Java!
От: Cyberax Марс  
Дата: 23.11.07 04:02
Оценка: 11 (5) +1 :)))
В соседнем треде был предложен тест между Java/ASP.NET и PHP (который предположительно будет быстрее).

Схема базы данных:
SET search_path = public, pg_catalog;
ALTER TABLE ONLY public.data DROP CONSTRAINT data_pkey;
ALTER TABLE ONLY public.users DROP CONSTRAINT users_pkey;
DROP TABLE public.data;
DROP SEQUENCE public.data_id_seq;
DROP TABLE public.users;
DROP SEQUENCE public.users_id_seq;
--
-- Definition for sequence users_id_seq (OID = 16435) : 
--
CREATE SEQUENCE users_id_seq
    INCREMENT BY 1
    NO MAXVALUE
    NO MINVALUE
    CACHE 1;
--
-- Structure for table users (OID = 16437) : 
--
CREATE TABLE users (
    id bigint DEFAULT nextval('users_id_seq'::regclass) NOT NULL,
    login varchar(64)
);
--
-- Definition for sequence data_id_seq (OID = 16445) : 
--
CREATE SEQUENCE data_id_seq
    INCREMENT BY 1
    NO MAXVALUE
    NO MINVALUE
    CACHE 1;
--
-- Structure for table data (OID = 16447) : 
--
CREATE TABLE data (
    id bigint DEFAULT nextval('data_id_seq'::regclass) NOT NULL,
    value text
);
--
-- Data for blobs (OID = 16437) (LIMIT 0,8)
--
INSERT INTO users (id, login) VALUES (1, 'user1');
INSERT INTO users (id, login) VALUES (2, 'user2');
INSERT INTO users (id, login) VALUES (3, 'user3');
INSERT INTO users (id, login) VALUES (4, 'user4');
INSERT INTO users (id, login) VALUES (5, 'user5');
INSERT INTO users (id, login) VALUES (6, 'user6');
INSERT INTO users (id, login) VALUES (7, 'user7');
INSERT INTO users (id, login) VALUES (8, 'user8');
--
-- Data for blobs (OID = 16447) (LIMIT 0,16)
--
INSERT INTO data (id, value) VALUES (15, 'loocamiolleh');
INSERT INTO data (id, value) VALUES (16, '54321');
INSERT INTO data (id, value) VALUES (17, '54321');
INSERT INTO data (id, value) VALUES (18, '54321');
INSERT INTO data (id, value) VALUES (19, '54321');
INSERT INTO data (id, value) VALUES (20, '54321');
INSERT INTO data (id, value) VALUES (21, '54321');
INSERT INTO data (id, value) VALUES (22, '54321');
INSERT INTO data (id, value) VALUES (23, '54321');
INSERT INTO data (id, value) VALUES (24, '54321');
INSERT INTO data (id, value) VALUES (25, '54321');
INSERT INTO data (id, value) VALUES (26, '54321');
INSERT INTO data (id, value) VALUES (27, '54321');
INSERT INTO data (id, value) VALUES (28, '54321');
INSERT INTO data (id, value) VALUES (29, '54321');
INSERT INTO data (id, value) VALUES (30, '54321');
--
-- Definition for index users_pkey (OID = 16440) : 
--
ALTER TABLE ONLY users
    ADD CONSTRAINT users_pkey PRIMARY KEY (id);
--
-- Definition for index data_pkey (OID = 16453) : 
--
ALTER TABLE ONLY data
    ADD CONSTRAINT data_pkey PRIMARY KEY (id);
--
-- Data for sequence public.users_id_seq (OID = 16435)
--
SELECT pg_catalog.setval('users_id_seq', 8, true);
--
-- Data for sequence public.data_id_seq (OID = 16445)
--
SELECT pg_catalog.setval('data_id_seq', 30, true);
--
-- Comments
--
COMMENT ON SCHEMA public IS 'Standard public schema'


Скрипт, использовавшийся для тестирования PHP:
<?
    /* ===[ Открыть соединение с БД ]==================================== */

    $host = "localhost";
    $dbname = "somedb";
    $user = "cyberax";
    $pass = "blahblah";

    $dbc = pg_connect ( "host=$host dbname=$dbname user=$user password=$pass" );
    if ( !$dbc ) die( "[1] Не возможно подключится к БД!" );
    /* ================================================================= */

    // получить MD5 от переменной "user" переданнной через POST запрос
    $user = md5( $_REQUEST["user"] );
    // запросить из таблицы "users" id записей, у которых есть такой login
    $q = pg_query( $dbc, "select id from users where md5(login)='$user'" );

    if ( $q === false ) echo( "[2] Не возможно сделать select из таблицы users!" );

    else 
        // если хоть одна запись существует - запускаем дальнейшую обработку
        if ( pg_num_rows( $q ) > 0 ) {
            // получаем тестовые данные через POST запрос
            $data = $_REQUEST["data"];
            if ( $data && $data != "" ) {
                // "мешаем" данные
                $len = strlen( $data );
                $len2 = $len / 2;
                for ( $i = 0, $j = $len - 1; $i < $len2; $i++, $j-- ) {
                    $t = $data[$i];
                    $data[$i] = $data[$j];
                    $data[$j] = $t;
                }
                // записываем получившиеся данные в БД
//PS: кстати, прекрасное место для SQL injection!!
                $q = pg_query( $dbc, "insert into data(value) values('$data')" );
                if ( $q == false ) echo( "[5] Не возможно сделать insert в таблицу data!" );
            }

            else echo( "[3] Входные данные отсутсвуют!" );
        
            // получаем случайную запись данных из БД
            $q = pg_query( $dbc, "select value from data order by random() limit 1" );
            if ( $q == false ) echo( "[5] Не возможно сделать select из таблицы data!" );
            @$r = pg_fetch_result ( $q, 0, "value" );
            echo( "[6] $r" );
        }

        else echo( "[4] Пользователь не найден!" );

    /* ===[ Close connect to Postgre SQL database ]====================== */
    pg_close( $dbc );
    /* ================================================================= */
?>

Для тестирования я использовал apache2, php5 и mod-php из стандартной поставки Debian (unstable), никакого дополнительного тюнинга не делал.

Для тестирования Java-версии я использовалось следующее приложение: http://files.rsdn.ru/37054/timetest.zip (собирается Maven'ом, деплоится в любой контейнер). Для удобства я подготовил приложение уже задеплоеное в Jetty и готовое к запуску, достаточно скачать http://sd-sup.staffdirector.net/JettyTest.zip (5Мб, на RSDN не поместилось) и поправить в нем в скрипте запуска "run.sh" параметры базы данных и путь до Java.

Тестирование проводил с помощью утиллиты 'ab' (Apache Benchmark). Каждый тест запускал трижды, выбирал наименьшее время работы. Перед каждым запуском база данных пересоздавалсь.

Первый раунд!

На ринге Java:
somehost:~# ab -c5 -n10000 http://somehost.staffdirector.net:8082/servlet/test-servlet?user=user2
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking somehost.staffdirector.net (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        Jetty(6.1.3)
Server Hostname:        somehost.staffdirector.net
Server Port:            8082

Document Path:          /servlet/test-servlet?user=user2
Document Length:        64 bytes

Concurrency Level:      5
Time taken for tests:   5.525140 seconds
Complete requests:      10000
Failed requests:        1150
   (Connect: 0, Length: 1150, Exceptions: 0)
Write errors:           0
Total transferred:      1467486 bytes
HTML transferred:       647486 bytes
Requests per second:    1809.91 [#/sec] (mean)
Time per request:       2.763 [ms] (mean)
Time per request:       0.553 [ms] (mean, across all concurrent requests)
Transfer rate:          259.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       3
Processing:     0    2   1.4      2      24
Waiting:        0    1   1.7      2      21
Total:          0    2   1.4      2      24

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      3
  90%      3
  95%      4
  98%      6
  99%      9
 100%     24 (longest request)

(на failed requests можно не обращать внимание — это глюки Apache Benchmark, все запросы завершились успешно).

На ринге PHP:
somehost:~# ab -c5 -n10000 http://somehost.staffdirector.net:8083/test.php?user=user2
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking somehost.staffdirector.net (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        Apache/2.2.6
Server Hostname:        somehost.staffdirector.net
Server Port:            8083

Document Path:          /test.php?user=user2
Document Length:        39 bytes

Concurrency Level:      5
Time taken for tests:   118.467055 seconds
Complete requests:      10000
Failed requests:        1167
   (Connect: 0, Length: 1167, Exceptions: 0)
Write errors:           0
Total transferred:      2787578 bytes
HTML transferred:       397578 bytes
Requests per second:    84.41 [#/sec] (mean)
Time per request:       59.234 [ms] (mean)
Time per request:       11.847 [ms] (mean, across all concurrent requests)
Transfer rate:          22.98 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0      25
Processing:    22   58  21.0     56     192
Waiting:       22   58  21.0     56     192
Total:         22   58  21.0     56     192

Percentage of the requests served within a certain time (ms)
  50%     56
  66%     64
  75%     69
  80%     73
  90%     85
  95%     98
  98%    114
  99%    125
 100%    192 (longest request)


Итак, в первом туре Java лидирует с двадцатикратным преимуществом!

Второй раунд!

На ринге Java:
somehost:~# ab -c5 -n10000 "http://somehost.staffdirector.net:8082/servlet/test-servlet?user=user2&data=testdata"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking somehost.staffdirector.net (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        Jetty(6.1.3)
Server Hostname:        somehost.staffdirector.net
Server Port:            8082

Document Path:          /servlet/test-servlet?user=user2&data=testdata
Document Length:        13 bytes

Concurrency Level:      5
Time taken for tests:   90.310586 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      950000 bytes
HTML transferred:       130000 bytes
Requests per second:    110.73 [#/sec] (mean)
Time per request:       45.155 [ms] (mean)
Time per request:       9.031 [ms] (mean, across all concurrent requests)
Transfer rate:          10.26 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       3
Processing:     2   44  43.4     29     373
Waiting:        0   44  43.4     29     373
Total:          2   44  43.4     29     373

Percentage of the requests served within a certain time (ms)
  50%     29
  66%     45
  75%     64
  80%     75
  90%    105
  95%    129
  98%    163
  99%    190
 100%    373 (longest request)

В данном тесте bottleneck'ом является скорость базы данных — в процессе теста постепенное замедление видно на глаз.

На ринге PHP:
somehost:~# ab -c5 -n10000 "http://somehost.staffdirector.net:8083/test.php?user=user2&data=testdata"           This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking somehost.staffdirector.net (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        Apache/2.2.6
Server Hostname:        somehost.staffdirector.net
Server Port:            8083

Document Path:          /test.php?user=user2&data=testdata
Document Length:        12 bytes

Concurrency Level:      5
Time taken for tests:   206.609725 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2510000 bytes
HTML transferred:       120000 bytes
Requests per second:    48.40 [#/sec] (mean)
Time per request:       103.305 [ms] (mean)
Time per request:       20.661 [ms] (mean, across all concurrent requests)
Transfer rate:          11.86 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    26  102  51.2     89     506
Waiting:       26  102  51.2     89     506
Total:         26  102  51.2     89     506

Percentage of the requests served within a certain time (ms)
  50%     89
  66%    110
  75%    127
  80%    140
  90%    174
  95%    202
  98%    239
  99%    267
 100%    506 (longest request)

Java опять побеждает — хотя и с меньшим отрывом, так как в этом тесте доминируют тормоза БД.

Результат: Java wins!
Sapienti sat!
Re: Mortal combat: PHP5 vs. Java!
От: Eugeny__ Украина  
Дата: 23.11.07 15:36
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В соседнем треде был предложен тест между Java/ASP.NET и PHP (который предположительно будет быстрее).


C>Результат: Java wins!


Тю, мне бы лень было тесты писать, эти и так ясно. Ладно я бы понял java vs asp.net, или тем более cgi на плюсах.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re[2]: Mortal combat: PHP5 vs. Java!
От: Cyberax Марс  
Дата: 23.11.07 17:04
Оценка:
Здравствуйте, Eugeny__, Вы писали:

C>>Результат: Java wins!

E__>Тю, мне бы лень было тесты писать, эти и так ясно. Ладно я бы понял java vs asp.net, или тем более cgi на плюсах.
С ASP.NET — будет примерно одинаковая производительность. Кто вырвется в лидеры будет зависеть от тюнинга виртуальных машин, операционок и web-серверов.

В cgi на плюсах — сложнее. Если использовать FastCGI и в самой CGI-шке сохранять соединение с БД между запросами — скорее всего будет быстрее Java. Но не на порядок, максимум в пару раз.
Sapienti sat!
Re: Mortal combat: PHP5 vs. Java!
От: Дм.Григорьев  
Дата: 26.11.07 12:09
Оценка: +4 :)
Здравствуйте, Cyberax,

Гы. Сравнил сам-знаешь-что с сам-знаешь-чем.

Впрочем, твои результаты могут пригодиться для тыканья носом заказчиков. Так что спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[2]: Mortal combat: PHP5 vs. Java!
От: int 13h Украина  
Дата: 01.12.07 14:54
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, Cyberax,


ДГ>Гы. Сравнил сам-знаешь-что с сам-знаешь-чем.

+1

ДГ>Впрочем, твои результаты могут пригодиться для тыканья носом заказчиков. Так что спасибо.



 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.