또 다른 합성 벤치 마크 : Sieve of Eratosthenes빠른 bitarray
C++
#include <vector>
#include <cmath>
void find_primes(int n, std::vector<int>& out)
{
std::vector<bool> is_prime(n + 1, true);
int last = sqrt(n);
for (int i = 2; i <= last; ++i)
{
if (is_prime[i])
{
for (int j = i * i; j <= n; j += i)
{
is_prime[j] = false;
}
}
}
for (unsigned i = 2; i < is_prime.size(); ++i)
{
if (is_prime[i])
{
out.push_back(i);
}
}
}
OCaml의 (사용 Jane Street's Core 및 Res 라이브러리)
open Core.Std
module Bits = Res.Bits
module Vect = Res.Array
let find_primes n =
let is_prime = Bits.make (n + 1) true in
let last = float n |! sqrt |! Float.iround_exn ~dir:`Zero in
for i = 2 to last do
if not (Bits.get is_prime i) then() else begin
let j = ref (i * i) in
while !j <= n; do
Bits.set is_prime !j false;
j := !j + i;
done;
end;
done;
let ar = Vect.empty() in
for i = 2 to n do
if Bits.get is_prime i then Vect.add_one ar i else()
done;
ar
나는이다 OCaml의 버전 (기본)에 놀랐다 C++보다 약 13 배 느리다. 나는 Res.Bits
을 Core_extended.Bitarray
으로 바꿨지 만 ~ 18 배 느려졌습니다. 왜 그렇게 느린가요? OCaml이 비트 조작에 대한 빠른 연산을 제공하지 않습니까? 비트 배열의 다른 빠른 구현이 있습니까?
분명히 : 나는 C++ 세계 출신이며 성능 중요한 코드를 작성할 수있는 대안으로 OCaml을 고려합니다. 사실, 나는 그런 결과에 약간 무서워.
는 편집 :는
프로파일 그것은 종종이 같은 마이크로 벤치 마크를 비교하는 것은 유용하지,하지만 기본적인 결론은 아마도 올
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
50.81 1.26 1.26 camlRes__pos_1113
9.72 1.50 0.24 camlRes__unsafe_get_1117
6.68 1.66 0.17 camlRes__unsafe_set_1122
6.28 1.82 0.16 camlNopres_impl__set_1054
6.07 1.97 0.15 camlNopres_impl__get_1051
5.47 2.10 0.14 47786824 0.00 0.00 caml_apply3
3.64 2.19 0.09 22106943 0.00 0.00 caml_apply2
2.43 2.25 0.06 817003 0.00 0.00 caml_oldify_one
2.02 2.30 0.05 1 50.00 265.14 camlPrimes__find_primes_64139
1.21 2.33 0.03 camlRes__unsafe_get_1041
...
시간을 어디에서 보내고 있는지 확인하기 위해 코드를 프로파일 링 했습니까? –
예. OCaml은 아직 충분하지 못하지만 gprof는 프로그램이 비트 어레이 조작에 대부분의 시간을 소비한다고 전했다. 나는 비트 Array를 일반 Array로 대체하려고 시도했지만 C++보다 3.3 배나 느려졌습니다. 분명히 비트 배열은 병 목입니다. – Stas
컴파일러 작성자의 경우 성능이 중요한 코드를 생성하는 것이 쉽지도 않으며 최악의 경우도 아닙니다. 대부분의 컴파일러 제작자 (Clang의 경우 제외)는 다음과 같은 방식으로 수행하려고합니다.) : C++, (젊은이가되고 싶다면 Java와 Fortran을 삽입하십시오.), Javascript (읽기 최적화 가이드), Ghc를 사용하는 Haskell ... 괜찮습니다. 그러나 그다지 중요하지 않습니다. 대부분은 LLVM을 사용하거나 Microsoft/Google을 사용하지 않습니다. 실제로 마이크로 소프트와 구글의 예산은 보증이 아니다 . – dsign