Чтобы сравнить производительность с медленными списками в этой ошибке GHC Я пытаюсь получить следующий цикл как можно быстрее:
{-# LANGUAGE BangPatterns #-}
module Main (main) where
import Control.Monad
import Data.Word
main :: IO ()
main = do
loop (maxBound :: Word32) $ \i -> do
when (i `rem` 100000000 == 0) $
print (fromIntegral i / fromIntegral (maxBound :: Word32))
loop :: Word32 -> (Word32 -> IO ()) -> IO ()
loop n f = go 0
where
go !i | i == n = return ()
go !i = f i >> go (i + 1)
скомпилирован с ghc -O loop.hs
.
Однако для этого требуется 50 секунд на моем компьютере - в 10 раз медленнее, чем эквивалентная программа на C:
#include "limits.h"
#include "stdint.h"
#include "stdio.h"
int main(int argc, char const *argv[])
{
for (uint32_t i = 0; i < UINT_MAX; ++i)
{
if (i % 100000000 == 0) printf("%f\n", (float) i / (float) UINT_MAX );
}
return 0;
}
скомпилирован с gcc -O2 -std=c99 -o testc test.c
.
Использование недавно выпущенного GHC 7.8 или с помощью -O2
не улучшило производительность.
Однако компиляция с флагом -fllvm
(в любой версии ghc) привела к улучшению скорости 10x, приведя производительность на уровне с помощью C.
Вопросы:
- Почему GGC native codegen настолько медленнее для моего
loop
? - Есть ли способ улучшить мой цикл так, чтобы он был быстрым и без
-fllvm
, или это уже самый быстрый цикл IO надWord32
, который можно достичь?