この違いを引き起こす可能性があることについてお聞きしたいと思います。以下のプログラムをコンパイルして同じバイナリを実行すると、一部のプラットフォームではC++コードの結果がハスケルのコードよりもはるかに高速ですが、他の状況は逆です。C++とHaskellのコードは、異なるマシンで実行時間が異なります
追加ビルドされたプラットフォームに応じて、最終的なバイナリのパフォーマンスに大きな違いがあります。 (各プラットフォームは同じフラグと同じバージョンのLVMとclangを使用します)
コードは最適化されており、同等のパフォーマンスで動作する必要があります。Can Haskell optimize function calls the same way Clang/GCC does?を参照してください。
どうすれば可能ですか?
C++コード:ghc -O3 --make -fforce-recomp -fllvm ghc-test.hs
結果(SAMEバイナリ上試験でコンパイル
module Main where
import qualified Data.Vector as V
import System.Environment
b :: Int -> Int
b x = x + 5
c x = b x + 1
d x = b x - 1
a x = c x + d x
main = do
putStrLn "Starting..."
args <- getArgs
let iternum = read (head args) :: Int in do
putStrLn $ show $ V.foldl' (+) 0 $ V.map (\i -> a (iternum-i))
$ V.enumFromTo 1 iternum
putStrLn "Done."
:clang++ -O3 main.cpp
Haskellコードでコンパイル
#include <cstdio>
#include <cstdlib>
int b(const int x){
return x+5;
}
int c(const int x){
return b(x)+1;
}
int d(const int x){
return b(x)-1;
}
int a(const int x){
return c(x) + d(x);
}
int main(int argc, char* argv[]){
printf("Starting...\n");
long int iternum = atol(argv[1]);
long long int out = 0;
for(long int i=1; i<=iternum;i++){
out += a(iternum-i);
}
printf("%lld\n",out);
printf("Done.\n");
}
私は、次のプログラムをコンパイルし、同じバイナリを実行する場合、異なるプラットフォーム)
// binaries compiled on Ubuntu:
Ubuntu x64 @ Intel i7-3610QM CPU @ 2.30GHz : C++:0.775s, GHC:1.01s
Gentoo x64 @ Intel i7-Q720 CPU @ 1.6GHz : C++:3.6s, GHC:2.1s
// binaries compiled on Gentoo:
Ubuntu x64 @ Intel i7-3610QM CPU @ 2.30GHz : C++:0.782s, GHC:1.01s
Gentoo x64 @ Intel i7-Q720 CPU @ 1.6GHz : C++:2.3s, GHC:1.3s
コンパイラの出力は、さまざまなチップセットに対して最適化できます。私はあなたの最後の質問について言ったことを繰り返します:アセンブリの出力を確認してください。 – chrisaycock
@chrisaycock前回はあなたのコメントが見えませんでした - 私はそれを実行します –
@ H2CO3: "C++はコンパイルされた言語です、ハスケルは解釈済みです"これは誤りです。 GHCはコンパイラです。ネイティブコードを生成します。言語は本質的に解釈もコンパイルもされませんが、C++を含む実用的な言語用のインタープリタやコンパイラを書くことができます。 –