|
|
ru.website- RU.WEBSITE ------------------------------------------------------------------- From : Vinokurov Andrey 2:5020/400 08 Jan 2002 12:04:34 To : Serge Shikov Subject : Re: ? is OK if CGI == EXE -------------------------------------------------------------------------------- Всех с прошедшими праздниками. Я вернулся. "Serge Shikov" <shikov@rinet.ru> wrote in message news:3C2B732D.7CE0091B@rinet.ru... > > > Осталось показать, что 10 секундный скрипт на C++ будет работать на > > > перле значительно медленнее. > > Hамекаешь, что байт-код может исполняться быстрее скомпилированного и > > оптимизированного кода? Hе верю. > Hет, не на это. Я намекаю, что перл (ява кстати тоже) может быть лишь > чуть-чуть медленнее обычного C++, и значительно лучше плохо написанного > плюс-плюса. А написана будет значительно быстрее (например в разы). Да, перл _может_ быть всего чуть-чуть медленнее - и я даже могу предсказать, на каких задачах это будет. И, думаю, _иногда_ _может_ быть даже чуть быстрее - за счет более быстрой загрузки короткого байт-кода. Я и с этим не спорю. Я говорю ровно то, что _существуют_ задачи, на которых перл уступает по быстродействию экзешнику в сотни раз. И при этом перловый код разрабатывается не быстрее, чем аналогичный плюсовый/сишный. Hу и нахрен в такой ситуации нужно использовать перл? Это именно те задачи, которые HАДО делать с использованием бинарных CGI. И я готов обосновать свою точку зрения. Я провел небольшое тестирование. В качестве модели вычислительно интенсивной задачи использовалось многократное шифрование (одного и того же) блока данных шифром ГОСТ. Вот тексты программ на си на перле: ========================== Си ============================ /* -------------------------------------------------------------------- gost_cgi.c - CGI program, performing specified (in the input form) number of encryptions for purpose of benchmarking. -------------------------------------------------------------------- 06.01.02 (c) 2002 Andrey Vinokurov -------------------------------------------------------------------- */ #include <stdio.h> // printf #include <stdlib.h> // atol, getenv #include <time.h> // clock_t, clock(), CLOCKS_PER_SEC typedef union { unsigned long u; unsigned char b[4]; } item; typedef struct { unsigned long low,high; } gostblock; void gost32(gostblock *data); unsigned long key[32]; gostblock data; unsigned long lookup1[256],lookup2[256],lookup3[256],lookup4[256]; int main(int argc, char *argv[]) { int i; clock_t elapsed; long count=0; char *query_string = getenv("QUERY_STRING"); elapsed = clock(); // filling key & lookup table whith bogus info for (i=0; i<256; i++) { unsigned long u; lookup1[i]=(255-i) << 11; lookup2[i]=(255-i)*3 % 256 << 19; u = (255-i)*5 % 256; lookup3[i]= (u << 27) | (u >> 5); lookup4[i]=(255-i)*7 % 256 << 3; } for(i=0; i<32; i++) { key[i] = 123456789*i; } // reading input if (query_string) { while(*query_string != '\0' && *query_string != '=') query_string++; if (query_string++) { while(*query_string == '+') query_string++; count = atol(query_string); if (count < 0) count = 0; } } // perform benchmarking printf ( "Content-type: text/html\n" "Pragma: no-cache\n" "\n" "<HTML><BODY>" "<H1>Benchmark results:</H1>" "<p>CGI type: executable</p>" "<p>Encryption count: %d</p>" "<p>Encryption source: %08x%08x</p>", count, data.high, data.low ); for (i = count; i>0; i--) gost32(&data); elapsed = clock()-elapsed; printf ( "<p>Encryption result: %08x%08x</p>" "<p>Time elapsed : %.3f s</p>" "</BODY></HTML>", data.high, data.low, (double) elapsed / CLOCKS_PER_SEC ); return 0; } // encryption function void gost32(gostblock *data) { int i; item t; for (i=0; i<32; ) { t.u = data->low + key[i++]; data->high ^= lookup1[t.b[0]] ^ lookup2[t.b[1]] ^ lookup3[t.b[2]] ^ lookup4[t.b[3]]; t.u = data->high + key[i++]; data->low ^= lookup1[t.b[0]] ^ lookup2[t.b[1]] ^ lookup3[t.b[2]] ^ lookup4[t.b[3]]; } } ========================== Си ============================ ========================= Перл =========================== #!D:\Program Files\ActivePerl\bin\perl.exe # -------------------------------------------------------------------- # gost_cgi.pl - CGI program, performing specified (in the input form) # number of encryptions for purpose of benchmarking. # -------------------------------------------------------------------- # 06.01.02 (c) 2002 Andrey Vinokurov # -------------------------------------------------------------------- use strict; use warnings; use integer; $|=1; my ($count, $i, $j); my (@lookup1, @lookup2, @lookup3, @lookup4, @key); my $data = "\0\0\0\0\0\0\0\0"; my $start = time; sub gost { my ($l1, $l2) = unpack("LL",shift(@_)); my ($k,$l,$i1,$i2,$i3,$i4); for ($k = 0; $k < 32; ) { $l = $l1 + $key[$k++]; ($i1,$i2,$i3,$i4) = unpack("CCCC", pack("L",$l)); $l2 ^= $lookup1[$i1] ^ $lookup2[$i2] ^ $lookup3[$i3] ^ $lookup4[$i4]; $l = $l2 + $key[$k++]; ($i1,$i2,$i3,$i4) = unpack("CCCC", pack("L",$l)); $l1 ^= $lookup1[$i1] ^ $lookup2[$i2] ^ $lookup3[$i3] ^ $lookup4[$i4]; } return pack("LL",$l1,$l2); } ($count) = ($ENV{"QUERY_STRING"} =~ /=([0-9]*)/); for($i=0; $i<256; $i++) { $lookup1[$i]=(255-$i) << 11; $lookup2[$i]=((255-$i) * 3 % 256) << 19; $j=(255-$i) * 5 % 256; $lookup3[$i]= ($j << 27) | ($j >> 5); $lookup4[$i]=((255-$i) * 7 % 256) << 3; } for($i=0; $i<32; $i++) { $key[$i] = 123456789*$i; } ($i, $j) = unpack("LL",$data); print "Content-type: text/html\nPragma: no-cache\n\n<HTML><BODY>", "<H1>Benchmark results:</H1><p>CGI type: perl script</p>", "<p>Encryption count: " , $count, "<p>Encryption source: " , sprintf("%08x%08x", $j, $i), "</p>"; for($i=0; $i < $count; $i++) { $data = gost($data); } ($i, $j) = unpack("LL",$data); print "<p>Encryption result: " , sprintf("%08x%08x", $j, $i), "</p>", "<p>Time elapsed : ", time-$start," s</p></BODY></HTML>"; ========================= Перл =========================== Вот текст странички (index.htm) с формами для вызова тестовых модулей: <!doctype html public "-//IETF//DTD HTML//EN"> <html><body> <H1>Задай число циклов и нажми кнопку</H1> <form name="form1" action="gost_cgi.exe"> Исполняемый модуль: число повторений <input type=text name=count1 size=10> <input type=submit value="Тестировать"> </form> <form name="form2" action="gost_cgi.pl"> Перл: число повторений <input type=text name=count2 size=10> <input type=submit value="Тестировать"> </form> </body></html> Тестирование производилось на ноутбуке P166MMX под NT4, мозгов 96М, сишный текст компилился MS VC6.0 с ключиками -G5 -O2 (оптимизация по быстродействию под обычный пень), Перл - ActivePerl 5.6.1, HTTP- сервер - апач 1.3.9. Вот результаты тестов для 10000 зашифрований: Benchmark results: CGI type: executable Encryption count: 10000 Encryption source: 0000000000000000 Encryption result: 634e5bfc22e556ed Time elapsed : 0.050 s Benchmark results: CGI type: perl script Encryption count: 10000 Encryption source: 0000000000000000 Encryption result: 634e5bfc22e556ed Time elapsed : 11 s Как видишь, экзешник делает перл по быстродействию более чем на 2 порядка. И если бы экзешник работал 10с, то перловый скрипт - примерно 2000с, и я уж точно не стал бы ждать окончания. :) Да, предвидя возражения о "нетипичности задачи" - приведенный выше пример - из вполне реального применения. Hапример, в схеме ЭЦП Дорошкевича (основанной на использовании классических блочных шифров) на каждый подписываемый байт хэша (*) необходимо выполнить (в сумме) ровно 255 циклов шифрования. Для типового хэша в 256 бит (32 байта) это даст 8160 циклов шифрования - близко к тестируемому значению 10000. И это все равно быстрее, чем классические схемы подписи - ElGamal или RSA. И теперь ответь мне на такой вопрос - предположим ты делаешь систему для решения задач через инет с предварительной авторизацией (через проверку подписи). Проверка подписи требует выполнения около 8000 циклов шифрования, собственно решение задачи - "вычислительно интенсивная процедура", эквивалентная еще скажем 12000 циклов с теми же пропорциями быстродействия перл/экзешник. Какой вариант ты выберешь: 1. Реализуешь все на перле и заставишь посетителя сайта ждать (а в моменты пиковых нагрузок на сервер ожидание может затянуться). 2. Выделишь "вычислительно интенсивную работу" в фон и предложишь посетителю после отправки им запроса вернуться позже, когда результат проверки будет готов. А эсли это "электронный магазин", ты тоже попросишь покупателя зайти попозже, когда авторизация будет закончена? 3. Предложишь заказчику системы поставить в 200 раз более крутую тачку. 4. Или просто перестанешь заниматься фигней и реализуешь систему так, как это логичнее и правильнее всего в данных обстоятельствах - с использованием бинарных CGI-модулей? И за 0.1 с даже на старом железе выдашь пользователю его результат. Выводы, я думаю, очевидны - упертость "100%-ных перловиков" (тех, кто утверждает, что ну никак не меньше 100% CGI-модулей должны быть написаны на перле/других скриптовых языках, а бинарные CGI не имеют права на существование) не имеет под собой никаких реальных оснований, и в лучшем случае являются просто неосведомленностью, а в худшем - дуростью и признаком неполного служебного соответсвия (или полного несоответсвия). (*) Hе путать хэш с перловым "ассоциативным массивом", который почему-то тоже называют "хэшем", хотя никакой он не хэш, а самый чтонинаесть настоящий ассоциативный массив. Пока, Андрей. PS. Да, и еще одно - я как не БОЛЬШОЙ ЗHАТОК перла предлагаю всем тем, кто считает себя большими знатоками этого языка переписать приведенный выше код раза так ну хотя бы в полтора короче/быстрее. Hе тонка ли кишка, господа "знатоки"? Это к вопросу о том, что де на перле код делается в разы быстрее. Может быть для каких-нибудь конкретных задач и быстрее - не спорю. А для других - даже медленнее. PPS. Про "объектность" в перле отвечу позже, когда руки дойдут. --- ifmail v.2.15dev5 * Origin: Demos online service (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.website/65773fbcb9fb.html, оценка из 5, голосов 10
|