Как добиться хорошей производительности при записи в файл списка целых чисел от 1 до 10 миллионов?

вопрос

Мне нужна программа, которая будет записывать в файл последовательность вроде

1
...
10000000

. Какой простейший код можно написать и получить достойную производительность ? Моя интуиция подсказывает, что есть некоторая проблема-отсутствия-буферизации. Мой код C работает со скоростью 100 МБ/с, тогда как, судя по ссылке, утилита командной строки Linux ddработает со скоростью 9 ГБ/с 3 ГБ/с (извините за неточность, см. комментарии --Хотя меня больше интересуют большие картины-масштаба-величины).

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

Код C

#include <stdio.h>

int main(int argc, char **argv) {
    int len = 10000000;
    for (int a = 1; a <= len; a++) {
        printf ("%d\n", a);
    }
    return 0;
}

Я компилирую с помощью clang -O3. Каркас производительности, который вызывает putchar('\n')8 раз, обеспечивает сравнимую производительность.

Код на Haskell

Простая реализация на Haskell работает со скоростью 13 МБ/с, компилируется с ghc -O2 -optc-O3 -optc-ffast-math -fllvm -fforce-recomp -funbox-strict-fields. (Я не перекомпилировал свои библиотеки с помощью -fllvm, возможно, мне нужно это сделать. )Код:

import Control.Monad
main = forM [1..10000000 :: Int] $ \j -> putStrLn (show j)

Моя лучшая попытка с Haskell работает еще медленнее, со скоростью 17 МБ/с. Проблема в том, что я не могу найти хороший способ преобразовать Vectorв ByteStringв (, возможно, есть решение с использованием итераций?).

import qualified Data.Vector.Unboxed as V
import Data.Vector.Unboxed (Vector, Unbox, (!))

writeVector :: (Unbox a, Show a) => Vector a -> IO ()
writeVector v = V.mapM_ (System.IO.putStrLn. show) v

main = writeVector (V.generate 10000000 id)

Кажется, что запись ByteStringвыполняется быстро , как показано в этом коде, запись эквивалентного количества символов,

import Data.ByteString.Char8 as B
main = B.putStrLn (B.replicate 76000000 '\n')

Получается 1,3 ГБ/с, что не так быстро, как dd], но, очевидно, намного лучше.

7
задан Anton Korobeynikov 10 April 2012 в 07:52
поделиться