LINUX.ORG.RU

Результаты теста скорости языков C++, Java, PHP, Ocaml, Perl, Python, Ruby...


0

1

Периодически появляются темы, в которых сторонники разных языков утверждают, что их языки быстрее/лучше. Захотелось это проверить. В паре тредов в качестве примера упоминались конкретные тесты. Их я и реализовал.

Общая идея теста

Тест проводится на каком-либо примере, позволяющем проверить производительность в той или иной области.

Реализация для каждого языка должна быть максимально простой. Если для данного языка нет простой реализации поставленной задачи - такой язык не подходит для решения этой задачи. Если простого решения задачи нет ни на одном языке - такая задача не подходит для теста.

Замер выполнялся десяток раз и для каждого языка выбиралось наилучшее время. Чем время меньше - тем лучше.

.

Числодробилки: длинная арифметика

Проверялась скорость операций с длинной арифметикой. Это важно в мат.вычислениях, требующих высокой точности. Реализация на примере вычисления факториала числа 30000.

$ make
Language            real     user   system
c++                0.179    0.175    0.004
php                0.307    0.292    0.015
perl (gmp)         2.045    2.041    0.004
ocaml              2.109    1.840    0.269
ocaml (recurse)    5.015    4.743    0.271
java               8.422    8.571    0.176
ruby               8.974    8.963    0.007
python            17.609   17.602    0.004
bc                49.716   49.607    0.099
perl             123.891  123.840    0.014

Замечание: Хотя нерекурсивная версия для ocaml-а написана «не совсем» в функциональном стиле, она работает в два с половиной раза быстрее, чем рекурсивная. Почему?

.

Объекты: создание и удаление

Проверялась скорость создания и удаления объектов. Это важно в ООП-задачах при передаче объектов, как параметров. Реализация теста подсказана форумом (последнее время недоступен)

$ make
Language           real      user   system
c++ (stack)       0.614     0.613    0.000    <1 MB
c++ (heap)       11.489    11.484    0.002    <1 MB
c++ (pool)        1.929     1.909    0.001    <1 MB
java              2.703     2.511    0.185   170 MB
ocaml           100.633   100.301    0.152     1 MB
python          389.973   389.882    0.009     3 MB
php             535.231   535.064    0.011     7 MB
ruby            756.593   680.874   75.535     3 MB
perl           4549.582  4548.612    0.027     3 MB

Замечание1: Можно было бы оставить только один тест для С++, но любители Java могли бы возмутиться, что C++ выделяет объект в стеке, а Java - в heap-е, и это нечестно по отношению к Java (и к тому же не возможно при большой глубине рекурсии и больших объектах). Потому добавлен С++ heap-тест (т.к. в Java для таких объектов автоматическое управление памятью, пришлось использовать его аналог - auto_ptr в С++).

Но тут сторонники С++ могли возмутиться, что С++-ный аллокатор оптимизирован для выделения больших объектов, и работает неэффективно для частого мелкого выделения. Поэтому был добавлен тест с более подходящим аллокатором (boost::object_pool).

Замечание2: Поскольку тест работал с памятью, логично было замерять, сколько же памяти в нем используется. И из всех тестируемых языков java - единственный, потребовавший 170МБ. Остальные уложились в десяток.

.

Выводы (если очень хочется): ООП-задачи кроме как на С++ и Java эффективно решать больше не на чем (но если важна память - остается только С++). А задачи, требующие высокой точности вычислений, быстрее всего решаются на С++. Его догоняют языки, умеющие работать с сишной libgmp, хотя и они примерно на порядок отстают от С++ по скорости.

Воспроизвести результаты можно скачав архив с тестами, и выполнив make в bash-е (для замера использовался bash-евый time, чтобы заменить его на что-то свое - надо править Makefile).

Все коды GPLv3+, можно их модифицировать, дополнять своими языками и выкладывать, куда угодно. Если есть еще примеры задач, на которых можно было бы провести тест, реализации тестов на других языках, или способы улучшения имеющихся (как ускорить perl?) - предлагайте. :)

>>> Исходники теста


Ответ на: комментарий от sergem

> В таком цикле и правда непонятно, что меряется. В нем вообще можно было выкинуть цикл,

Пошли типично крестофильские отмазки. Ещё один факториал тоже нахер никому не нужен, но тебя же это не останавливает?

> Будет версия на lisp-е? ;)


Сначала 2 + 2 ускорь.

mv ★★★★★
()

Вообще бестолковые тесты, и особенно с фибоначи.
Кстати ,следует еще смотреть и ruby 1.9 для факториала (я сам добавил):

Language real user system
java 8.088 7.784 0.076
ruby1.9 3.169 3.076 0.028
python 16.382 14.965 0.004
bc 44.189 42.983 0.152
perl 95.883 93.222 0.028

и довольно бодренько ruby 1.9 тут смотрится :))

elipse ★★★
()
Ответ на: комментарий от elipse

и еще замер:

Language real user system
java 8.187 7.588 0.156
ruby1.9 3.336 3.088 0.012
ruby1.8 8.271 8.097 0.028
python 15.144 14.853 0.012
bc 44.927 43.011 0.220
perl 97.046 94.230 0.032

elipse ★★★
()
Ответ на: комментарий от KRoN73

> Разные платформы дают нелинейные соотношения производительности. Вплоть до того, что разные языки оказываются взаимно разными по скорости. Скажем, в числодробилке Java может сильно обходить C++ на Intel'ах и несколько отставать на AMD.

Проверил. Тесты в шапке делались на AMD Athlon X2 3800+

c++                0.179    0.175    0.004
perl (gmp)         2.045    2.041    0.004
java               8.422    8.571    0.176
perl             123.891  123.840    0.014

Теперь тот же тест на Intel Xeon 3.00GHz

c++                0.171    0.167    0.002
perl (gmp)         1.279    1.259    0.007
java               5.070    4.920    0.092
perl              72.689   72.365    0.055

Соотношения работают с точностью до погрешности измерений. :)

sergem
() автор топика
Ответ на: комментарий от sergem

Соотношения работают с точностью до погрешности измерений. :)

Ок, берём С++ за единицу (user).

Тогда на AMD: perl (gmp) = 11,6 java = 49,0 perl = 707

На Intel: perl (gmp) = 7,5 java = 29,4 perl = 433

Судя по всему над погрешностью измерений ещё работать и работать.

KRoN73 ★★★★★
()
Ответ на: комментарий от sergem

> И еще чтобы проверить на практике фразы вроде "java не медленнее C++" или "функциональные языки для числодробилок лучше".

Так и непонятно, что именно ты проверяешь своими тестами. И причем здесь "java не медленнее C++", если ты юзаешь библиотеки? А с объектами, вообще, туманно.

Для проверки есть ray-tracer. В теме про "[C++] Несерьезный вопрос" можно найти ссылку (последняя из двух).

dave ★★★★★
()
Ответ на: комментарий от elipse

> Вообще бестолковые тесты, и особенно с фибоначи.

Слово "бестолковые" значит, что есть более толковые? Какие? И чем эти плохи?

> и довольно бодренько ruby 1.9 тут смотрится :))

Да. Даже рекурсивную версию для ocaml немного опередил.

PS: как жаль, что нельзя редактировать шапку...

sergem
() автор топика
Ответ на: комментарий от dave

> Так и непонятно, что именно ты проверяешь своими тестами. И причем здесь "java не медленнее C++", если ты юзаешь библиотеки?

Дело не в библиотеках, а в языке. Есть много языков, которые позволяют просто работать с большими числами. Какой из них выбрать?

Скажем, если надо написать программу, работающую с большими простыми числами (задача, иногда возникающая при шифровании), или программу, проверяющую простоту числа (типа GIMPS), или любую другую программу, требующую длинной арифметики - на каком языке мне ее написать?

И на С++, и на Java и на Python-е, и на Perl-е она реализуется одинаково просто. Но какая из них будет работать быстрее?

sergem
() автор топика
Ответ на: комментарий от sergem

> Дело не в библиотеках, а в языке. Есть много языков, которые позволяют просто работать с большими числами. Какой из них выбрать?

Ты определись: либо ты меряешь сверическое умение работать с большими числами в вакууме -- тогда выкинуть отовсюду libgmp, где он не встроен в язык и не говорить про практическое применение; либо ты меряешь с учётом практики, тогда задачу надо решать оптимальным для каждого языка образом, а не сферическим методом, лучше подходящим под какой-то один язык (наиболее известный автору, очевидно).

kemm
()
Ответ на: комментарий от kemm

мордарука.жыпыгы

s/сверическое/сферическое/g

kemm
()
Ответ на: комментарий от kemm

> либо ты меряешь с учётом практики, тогда задачу надо решать оптимальным для каждого языка образом ...

Именно так. Задача - замерять скорость операций длинной арифметики в разных языках. Я решил эту задачу "неоптимально"? Мое решение - умножить между собой числа от 1 до 30000 и засечь время данной операции. Какое решение "оптимальнее"? Есть конкретные предложения?

sergem
() автор топика
Ответ на: комментарий от sergem

>> либо ты меряешь с учётом практики, тогда задачу надо решать оптимальным для каждого языка образом ...

> Именно так. Задача - замерять скорость операций длинной арифметики в разных языках.

Я и говорю, определись окончательно. Цитата из начала треда:

> Все задачи писались максимально эквивалентным кодом (например, для вычисления факториала использован примерно одинаковый цикл во всех языках с точностью до синтаксиса).

kemm
()
Ответ на: комментарий от sergem

>Соотношения работают с точностью до погрешности измерений. :)

facepalm.jpg

Речь о плавающей точке наверно идет а не о BigDecimal'ах.

Absurd ★★★
()
Ответ на: комментарий от kemm

> Я и говорю, определись окончательно.

Я-то определился. Я решаю не задачу "факториал", а задачу "измерять скорость операций". Чтобы решать такую задачу - надо сравнивать одинаковые или, с учетом разницы в синтаксисе, максимально одинаковые операции. Потому и:

> Цитата из начала треда:

>> Все задачи писались максимально эквивалентным кодом (например, для вычисления факториала использован примерно одинаковый цикл во всех языках с точностью до синтаксиса).

Еще раз. Я не пытаюсь вычислить факториал или узнать 40-е число Фибоначчи. Для этого есть более эффективные методы. Я замеряю скорость. А "факториал" и "фибоначчи" - всего лишь слова, подсказавшие мне способ замера. :)

sergem
() автор топика
Ответ на: комментарий от sergem

>Мое решение - умножить между собой числа от 1 до 30000 и засечь время данной операции.

Ну и получишь ты везде луп из трех call'ов - сравнение, вычитание и умножение. Не считая обвязки из mov-ов, конечно.

Absurd ★★★
()
Ответ на: комментарий от mv

>> PS: Где же варианты реализаций от любителей хаскеля?

> http://www.willamette.edu/~fruehr/haskell/evolution.html

Я не знаю хаскель. Можно увидеть полный код, включающий чтение числа из первого параметра командной строки и вывода результата вычисления на экран?

sergem
() автор топика
Ответ на: комментарий от Absurd

> Ну и получишь ты везде луп из трех call'ов - сравнение, вычитание и умножение. Не считая обвязки из mov-ов, конечно.

Ну да. В теории. И в теории я должен получить одинаковую скорость на всех компилируемых языках и близкую скорость на интерпретируемых. Практика же показывает, что скорости отличаются в десятки раз.

sergem
() автор топика
Ответ на: комментарий от sergem

> Можно увидеть полный код, включающий чтение числа из первого параметра командной строки и вывода результата вычисления на экран?

А лучше было бы сразу два варианта, как для Ocaml: рекурсивный и циклический. А то вдруг опять "некрасивый" циклический вариант с присваиваниями окажется в 2 раза быстрее...

sergem
() автор топика
java -client Fib 40                        2.65
java -server Fib 40                        1.63
java -server -XX:+DoEscapeAnalysis Fib 40  0.94
kamre ★★★
()
Ответ на: комментарий от sergem

на лиспе вот:
фибоначчи:
http://paste.lisp.org/display/88843
факториал, нативные бигнамы, без всяких там gmp:
http://paste.lisp.org/display/88844

скорость в сравнении с плюсами(правда, под оффтопик под mingw):
фибоначчи:
http://pic.ipicture.ru/uploads/091018/yAP6s5ZX46.png
факториал:
http://pic.ipicture.ru/uploads/091018/eT02DoO4E6.png

Love5an
()
Ответ на: комментарий от sergem

Ну и получишь ты везде луп из трех call'ов - сравнение, вычитание и умножение. Не считая обвязки из mov-ов, конечно.

Ну да. В теории. И в теории я должен получить одинаковую скорость на всех компилируемых языках и близкую скорость на интерпретируемых. Практика же показывает, что скорости отличаются в десятки раз.

Ну вот факториал на лиспе, например

(defun !(n) (labels ((!- (acc n) (if (> n 1) (!- (* acc n) (- n 1)) acc))) (!- 1 n)))

Вот его дизассемблер. - Видим три call-a

; 02BD17BD:       488B4DD8         MOV RCX, [RBP-40]          ; no-arg-parsing entry point
;      7C1:       F6C107           TEST CL, 7
;      7C4:       7417             JEQ L0
;      7C6:       8BC1             MOV EAX, ECX
;      7C8:       240F             AND AL, 15
;      7CA:       3C0F             CMP AL, 15
;      7CC:       0F858E000000     JNE L4
;      7D2:       8A41F1           MOV AL, [RCX-15]
;      7D5:       3C12             CMP AL, 18
;      7D7:       0F8583000000     JNE L4
;      7DD: L0:   BB08000000       MOV EBX, 8
;      7E2:       488B4DD8         MOV RCX, [RBP-40]
;      7E6:       48894DE8         MOV [RBP-24], RCX
;      7EA:       EB72             JMP L3
;      7EC: L1:   48895DE0         MOV [RBP-32], RBX
;      7F0:       488B55E8         MOV RDX, [RBP-24]
;      7F4:       BF08000000       MOV EDI, 8
;      7F9:       4C8D1C2550040020 LEA R11, [#x20000450]      ; GENERIC->
;      801:       41FFD3           CALL R11
;      804:       480F42E3         CMOVB RSP, RBX
;      808:       488B5DE0         MOV RBX, [RBP-32]
;      80C:       4881FA17001020   CMP RDX, 537919511
;      813:       750F             JNE L2
;      815:       488BD3           MOV RDX, RBX
;      818:       488D65F0         LEA RSP, [RBP-16]
;      81C:       F8               CLC
;      81D:       488B6DF8         MOV RBP, [RBP-8]
;      821:       C20800           RET 8
;      824: L2:   488B7DE8         MOV RDI, [RBP-24]
;      828:       488BD3           MOV RDX, RBX
;      82B:       4C8D1C25C9020020 LEA R11, [#x200002C9]      ; GENERIC-*
;      833:       41FFD3           CALL R11
;      836:       480F42E3         CMOVB RSP, RBX
;      83A:       488955E0         MOV [RBP-32], RDX
;      83E:       488B55E8         MOV RDX, [RBP-24]
;      842:       BF08000000       MOV EDI, 8
;      847:       4C8D1C254C020020 LEA R11, [#x2000024C]      ; GENERIC--
;      84F:       41FFD3           CALL R11
;      852:       480F42E3         CMOVB RSP, RBX
;      856:       488B5DE0         MOV RBX, [RBP-32]
;      85A:       488955E8         MOV [RBP-24], RDX
;      85E: L3:   EB8C             JMP L1
;      860: L4:   488B45D8         MOV RAX, [RBP-40]
;      864:       488B0DF5FEFFFF   MOV RCX, [RIP-267]         ; 'INTEGER
;      86B:       CC0A             BREAK 10                   ; error trap
;      86D:       03               BYTE #X03
;      86E:       1F               BYTE #X1F                  ; OBJECT-NOT-TYPE-ERROR
;      86F:       0F               BYTE #X0F                  ; RAX
;      870:       4F               BYTE #X4F                  ; RCX
;      871:       90               NOP
;      872:       90               NOP
;      873:       90               NOP
;      874:       90               NOP
;      875:       90               NOP
;      876:       90               NOP
;      877:       90               NOP
;      878:       90               NOP
;      879:       90               NOP
;      87A:       90               NOP
;      87B:       90               NOP
;      87C:       90               NOP
;      87D:       90               NOP
;      87E:       90               NOP
;      87F:       90               NOP
;      880:       CC0A             BREAK 10                   ; error trap
;      882:       02               BYTE #X02
;      883:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;      884:       4E               BYTE #X4E                  ; RCX
; 
Absurd ★★★
()

tcl 8.5.5

--------------------------

proc fact {n} { set result 1 while {$n > 1} { set result [expr {$result * $n} ] incr n -1 } return $result }

fact [lindex $argv 0]

--------------------------

real 0m4.645s

user 0m4.550s

sys 0m0.067s

anonymous
()
Ответ на: комментарий от sergem

>Выполнялась серия экспериментов (не меньше десятка, кроме перла, для него было всего 3 - ждать долго). Выбирался наилучший результат. Зачем наилучший? Чтобы исключить влияние других программ и демонов, случайные свопы на диск, обращения по сети и другие действия, которые могли замедлить программу.

Для одного из языков у тебя наилучший результат мог быть при более благоприятных обстаятельствах. Статистика рулит:) Самый простой вариант это - отбрасываешь самый лучший и самый худший вариант, остальное усредняешь.

golodranez ★★★★
()
Ответ на: комментарий от sergem

>> Можно увидеть полный код, включающий чтение числа из первого параметра командной строки и вывода результата вычисления на экран?

>А лучше было бы сразу два варианта, как для Ocaml: рекурсивный и циклический. А то вдруг опять «некрасивый» циклический вариант с присваиваниями окажется в 2 раза быстрее...

Неужели в треде нет ни одного хаскелиста? Навскидку написанная программа:

import System

factorial n =
  if n == 0 then
    1
  else
    n * factorial (n-1)

main = do
  [n] <- getArgs
  print (factorial (read n::Int))
Выдает неверный ответ.

А еще надо бы циклический нерекурсивный вариант, если такой возможен в хаскеле...

sergem
() автор топика
Ответ на: комментарий от sergem

> Неужели в треде нет ни одного хаскелиста?

Блин, тебе mv дал ссылку - там порядка 20-30 вариантов реализации факториала на хаскелле.

anonymous
()
Ответ на: комментарий от anonymous
> tcl 8.5.5
[...]
> real 0m4.645s
> user 0m4.550s
> sys 0m0.067s

То ли у меня очень медленный комп, то ли я делаю что-то не так.

tcl-8.5.3-1

$ cat fact.tcl
#!/usr/bin/tclsh

proc fact {n} {
    set result 1
    while {$n > 1} {
        set result [expr {$result * $n} ]
        incr n -1
    }
    return $result
}

puts stdout [fact [lindex $argv 0]]

$ time ./fact.tcl 30000 > /dev/null

real    1m16.448s
user    1m16.120s
sys     0m0.274s

Медленнее в 15 раз? Где ошибка?

sergem
() автор топика
Ответ на: комментарий от anonymous

>> Неужели в треде нет ни одного хаскелиста?

> Блин, тебе mv дал ссылку - там порядка 20-30 вариантов реализации факториала на хаскелле.

Блин, я взял первый же факториал из той ссылки, вставил в программу и получил НЕВЕРНЫЙ ответ. Внимательнее читать надо. :)

sergem
() автор топика
Ответ на: комментарий от sergem

> я взял первый же факториал из той ссылки,

Возьми последний.

mv ★★★★★
()
Ответ на: комментарий от sergem

>программу и получил НЕВЕРНЫЙ ответ

Хватит троллить, разводка известная.

Возьми факториал, который не будет использовать неупакованные ака "машинные" переменные. Будет тебе верный ответ, только медленней.

(Хотя это не отменяет тот факт, что лицам, использующим для хранения значений который растут с факториальной скоростью "машинные" типы данных следует отрывать руки)

Macil ★★★★★
()
Ответ на: комментарий от golodranez

> Для одного из языков у тебя наилучший результат мог быть при более благоприятных обстаятельствах.

Если бы тест был один или два - мог бы. А так - какими должны были быть эти обстоятельства?

Кроме того я хочу измерять максимально чистое время работы программы, а не время работы + усредненные помехи.

> Самый простой вариант это - отбрасываешь самый лучший и самый худший вариант, остальное усредняешь.

Это не самый простой вариант. Потому что надо хранить все результаты. А что делать, если их разное количество? Скажем, для питона их было штук двадцать, а для перла - всего несколько (он больше часа работает). Получается, что проще и правильнее считать минимальное время. :)

sergem
() автор топика
Ответ на: комментарий от sergem

puts stdout [fact [lindex $argv 0]]

Не делай puts много времени уходит на форматирование числа (перевод в строку)

sdio ★★★★★
()
Ответ на: комментарий от Macil

>>программу и получил НЕВЕРНЫЙ ответ

> Хватит троллить, разводка известная.

Какая разводка? Я спросил код - получил ссылку. Попросил полный код вместе со считыванием параметров и выводом на экран - не получил ничего. Попытался разобраться сам (это была моя первая программа на хаскеле), взял кусок кода из той "ссылки", погуглил остальные куски, почитал доки, написал что-то компилирующееся - оно выдало неверный ответ. Спросил помощи - обвинили в троллинге.

Ну и где тут "разводка"?

Я выложил десяток реализаций на разных языках. Попросил одну, и даже ее не получил.

Единственный полный код, который пока что был выложен - код на tcl от анонимуса (!). И даже в нем у меня не удалось воспроизвести результат (время не сошлось).

sergem
() автор топика
Ответ на: комментарий от sdio

>> puts stdout [fact [lindex $argv 0]]

> Не делай puts много времени уходит на форматирование числа (перевод в строку)

А как иначе вывести его на экран? Не выводить его я не могу. По двум причинам.

Во-первых, чтобы убрать вывод отсюда - придется выкинуть его и из остальных программ. Да и сколько он может занимать времени? Ну не минуту же?

Во-вторых, если его выкинуть, я получаю функцию, результат вычислений которой нигде не используется. Транслятор может запросто это заметить, и выкинуть вычисление. Получится, что именно то, что надо было замерять, было выброшено из кода. :)

sergem
() автор топика
Ответ на: комментарий от sergem

> Единственный полный код, который пока что был выложен

Тебе еще лисповый вариант выложили.

anonymous
()
Ответ на: комментарий от anonymous

>> Единственный полный код, который пока что был выложен

> Тебе еще лисповый вариант выложили.

Он, к сожалению, такой же, как и у хаскеля - только функция. Нет ни чтения параметра командной строки, ни вывода на экран.

PS (лисповцам): Может кто-то выложит полный вариант? Такой, который можно скомпилировать, запустить с параметром и увидеть на экране результат вычисления, как в остальных программах.

sergem
() автор топика
Ответ на: комментарий от sergem

>Какая разводка? Я спросил код - получил ссылку.

Да известная разводка для сбивания ЧСВ у быдлокодеров на всякого рода собеседованиях. Просишь написать функцию, вычисляющую факториал. И ловишь лулзы.

Ну да ладно. Будем думать что ты это не специально.

>Попытался разобраться сам (это была моя первая программа на хаскеле)


Ну явно ты не с того конца начал разбираться. Функции для вычисления факториалов и быстрой сортировки, которыми так любят завлекать новичков, в реале работают совсем не так, как от них ждешь.

Macil ★★★★★
()
Ответ на: комментарий от mv

>Из чего я в стиле крестовых фанбоев сделал бы вывод, что Лисп считает в 50 раз быстрее крестов. А если сложение сделать через функцию, то и во все 250.

Повторишь рекорд на операциях с плавающей точкой -- будешь крут :D

linuxfan
()
Ответ на: комментарий от sergem

>> Для одного из языков у тебя наилучший результат мог быть при более благоприятных обстаятельствах.

>Если бы тест был один или два - мог бы. А так - какими должны были быть эти обстоятельства?

>Кроме того я хочу измерять максимально чистое время работы программы, а не время работы + усредненные помехи.

Хм.. потому, что тебе правильно написали методику обработки экспериментальных данных, а ты все за свои велосипеды оценивающие сферическое время в вакууме.

Waterlaz ★★★★★
()
Ответ на: комментарий от anonymous

> Там же написано как запускать.

И где там чтение параметров командной строки или вывод результата на экран? Как узнать, вдруг там оптимизатор выкинул все вычисления за ненадобностью?

Далее, там запускается интерпретатор. А разве lisp-программу нельзя скомпилировать? Или скомпилированная она работает медленнее, чем запущенная из интерпретатора?

К тому же запуск из интерпретатора не совпадает с общей методикой теста, и такой замер нельзя провести, например, для С++. То есть замер получается нечестным / нечистым.

sergem
() автор топика
Ответ на: комментарий от Waterlaz

>>> Для одного из языков у тебя наилучший результат мог быть при более благоприятных обстаятельствах.

>>Если бы тест был один или два - мог бы. А так - какими должны были быть эти обстоятельства?

>>Кроме того я хочу измерять максимально чистое время работы программы, а не время работы + усредненные помехи.

>Хм.. потому, что тебе правильно написали методику обработки экспериментальных данных, а ты все за свои велосипеды оценивающие сферическое время в вакууме.

Какую еще методику обработки экспериментальных данных? Я что, меряю мат.ожидание нормально распределенной случайной величины?

PS: Логика цитирования интересная - процитировать два моих вопроса/утверждения, а затем в своем комментарии на них не ответить... :)

sergem
() автор топика
Ответ на: комментарий от sergem

>И где там чтение параметров командной строки
С этим сложно. Но зачем они так уж нужны?
>Как узнать, вдруг там оптимизатор выкинул все вычисления за ненадобностью?

Ага, так уж прям выкинул :) А целую секунду, или две, рантайм думает, нафига ж ему вычислять соптимизированную нафиг функцию подсунули :)
А для проверки достоверности можно вне теста, в repl, попробовать функции вызывать, да.
>Далее, там запускается интерпретатор.

Никакой не интерпретатор, во-первых(если только в значении REPL), потому как SBCL даже в repl весь код компилирует. А во-вторых, он компилирует файл с кодом, как видно, и тут же загружает его.
>К тому же запуск из интерпретатора не совпадает с общей методикой теста, и такой замер нельзя провести, например, для С++. То есть замер получается нечестным / нечистым.

Оно там делает все то же самое, что и в c++ варианте, почти, т.е. компилирует файл, загружает его, запускает скомпилированный код, передавая ему соответствующий параметр, и замеряет время вычисления оного кода, только вместо sh - лисповский топлевел, repl, а вместо линукса - рантайм лиспа :)

Love5an
()
Ответ на: комментарий от sergem

Это достаточно прямой ответ. min(выборки) - это сферический конь в вакууме.

Что ты надеешься получить таким образом?

"время работы + усредненные помехи" вероятно и есть найболее точная оценка.

Waterlaz ★★★★★
()
Ответ на: комментарий от Love5an

>> И где там чтение параметров командной строки

> С этим сложно. Но зачем они так уж нужны?

Для того, чтобы сделать:

$ ./fact_lisp 30
и посмотреть, что ответ правильный. Затем сделать:
$ ./fact_lisp 30000 | md5sum
и проверить, что ответ тоже правильный. Затем запустить:
$ for i in {1..10}; do time ./fact_lisp 30000 > /dev/null; done
и получить результат. Добавить его в общую таблицу и внести строчку для его замера в Makefile.

Как все это сделать без параметров? ;)

> Ага, так уж прям выкинул :) А целую секунду, или две, рантайм думает, нафига ж ему вычислять соптимизированную нафиг функцию подсунули :)

Ну, вот, в примере для tcl-я, если выкинуть вывод, то время выполнения уменьшается с 76 секунд, до 4. Наверное он там тоже 4 секунды думает, нафига ему это вычислять, да? ;)

Так что практика показывает, что и ввод и вывод нужен. Иначе сравнение превращается в соревнование «кто выкинет больше лишнего кода».

> Оно там делает все то же самое, что и в c++ варианте, почти, ...

В том-то и дело, что «почти». А для всех остальных языков замер делается иначе. Получается сравнение теплого с мягким (температуры с жесткостью). Ведь нельзя провести замер тем же методом для всех остальных языков. Получается, что эта конкретная программа находится не в таких же условиях, как все остальные.

sergem
() автор топика
Ответ на: комментарий от Waterlaz

> Это достаточно прямой ответ. min(выборки) - это сферический конь в вакууме.

> Что ты надеешься получить таким образом?

Время работы программы, конечно.

Еще раз, но подробнее. Каждый из элементов выборки дает мне "время работы + помехи". Где "время работы" - это постоянная величина, зависящая от языка (и компилятора), которая определяется только сгенерированными машинными кодами, не меняющимися от запуска к запуску. А "помехи" - положительная случайная величина, зависящая от состояния кеша процессора, положения головки на диске, наличия пакетов в сетевой карте, библиотек в памяти... Если теперь я хочу получить оценку величины "время работы", как мне это сделать с точки зрения мат.статистики?

> "время работы + усредненные помехи" вероятно и есть найболее точная оценка.

Это будет усредненная оценка помех на моей машине. Чем это увеличит качество эксперимента? Вроде бы цель была узнать время работы программы, а не исследовать влияние других компонентов системы на это время...

sergem
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.