LINUX.ORG.RU

Как это понимать???

 ,


0

1

Здравствуй, ЛОР! Опять я к тебе с вопросами.

Есть модуль myLen.hs:

{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP, MagicHash #-}
{-# OPTIONS_HADDOCK hide #-}

import GHC.Base

main = do
  st <- getLine
  putStrLn ( show ( mylen [1..rInt st] ) )

mylen :: [a] -> Int
mylen l =  len l 0#
  where
    len :: [a] -> Int# -> Int
    len []     a# = I# a#
    len (_:xs) a# = len xs (a# +# 1#)

rInt :: String -> Int
rInt = read

Он был откомпилирован командой:

ghc -o l -O2 myLen.hs

А в итоге имеем:

>ghci myLen.hs
GHCi, version 7.2.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Ok, modules loaded: Main.
Prelude Main> :set +s
Prelude Main> main
10000000
10000000
(0.53 secs, 399365024 bytes)
Prelude Main> main
100000000
100000000
(4.66 secs, 4002293340 bytes)
Prelude Main> main
1000000000
1000000000
(50.08 secs, 40000470100 bytes)
Prelude Main> length [1..10000000]
10000000
(1.06 secs, 404952660 bytes)
Prelude Main> length [1..100000000]
100000000
(9.94 secs, 4000357640 bytes)
Prelude Main> length [1..1000000000]
1000000000
(103.70 secs, 40000593384 bytes)
Prelude Main>
Leaving GHCi.

>

Как вообще это понимать? Я так понимаю, стандартная библиотека Prelude тоже откомпилирована? Почему же точно такая же функция из нее работает в 2 раза медленнее? O2 тут не при чем, потому что обнаружил эту хрень я как раз, когда компилировал код без этого флага.

★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Нет под рукой ghci А если length [1..100000000]::Int ?

kpavn
()

потому, что ghci не компилирует первую функцию.. И вообще для сравнения времени стоит использовать criterion :) в крайнем случае скомпилировать файл MyLen.hs и потом грузить его в ghci :m MyLen

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

Он скомпилированным и грузится. По сообщениям же видно.

delete83 ★★
() автор топика

Как вообще может прийти в голову сравнивать производительность в интерпретаторе?

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

Этот самый criterion вроде просто запускает прогу много раз и считает среднее отклонение времени выполнения. Или я слишком уж бегло посмотрел описание.

В данном случае это не актуально. Я и так несколько раз руками прогонял тесты и отклонения были незначительны по сравнению с самими результатами.

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

Мда. Все же я сглупил. В самом деле сравнивал результат вызова в интерпретаторе стандартной функции с вызовом откомпилированного модуля. Переписал тесты и сравнил два откомпилированных модуля: результат идентичны.

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

Возможно, что интерпретируемый список тормозил, тот самый, который подавался как аргумент функции length.

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

Ага, возможно. Об этом я тоже думал. Потому что если я не буду запрашивать max списка у пользователя, а просто зашью в код готовой цифрой, такой код по оценке ghci выполняется вообще мгновенно (0.00 c), а значит банально разворачивается в результат еще на этапе компиляции.

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

ну и отлично :)

а критерион да, сначала «разогревает проц», потом пускает прогу много раз, пытаясь вычислить среднее и стандартное отклонение, а так же учесть влияние внешних факторов, + есть управление поведением gc между тестами. Ну и всякие бонусы типа использования DeepSeq, для того, чтобы гарантировать, что не вернулся недосчитанный thunk. В общем, если тестить не им и предоставлять результаты, то с большой вероятностью можно получить ответ «не верю».

Единственный минус, я не нашёл как нахаляву «выдернуть» из него результаты, чтобы делать своё форматирование тестирования, или, например, вычислять оптимальные параметры функции.

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