Я написал действительно простую программу, чтобы сравнить производительность с Julia против C / C ++. По сути, он возвращает общее простое число меньше заданного числа. Проблема в том, что я получил среднее время в 2,5 раза хуже, чем в эквиваленте c / c ++ (AFAIK, оно должно быть несколько близко к 1,0x). Я использую Julia 0.5.0 (но я также тестировал на 0.6.0, получая тот же результат). Я узнал, что изменение %
за mod
сделать операцию модуля помогла. Кроме того, настройки типов везде дают мне некоторую выгоду.
Может кто-нибудь помочь мне выяснить, что еще мне не хватает, чтобы улучшить производительность Джулии в этом примере? Заранее спасибо.
module modIsPrime
export isprime, Test_isprime
@inline function isprime( nNumber :: Int64 ) :: Int64
s = Int( trunc( sqrt( nNumber ) ) )
if mod( nNumber, 2 ) == 0
return 0
else
for i = 3 : 2 : s
if mod( nNumber, i ) == 0
return 0
end
end
return 1
end
end
function Test_isprime( )
nPrimeNumbers :: Int64 = 0
n :: Int64 = 0
for n = 1 : 2 : 16000000
nPrimeNumbers += isprime( n )
end
display( [ "Prime numbers: " nPrimeNumbers ] )
end
end
Редактировать — как упоминал Рон, вот код C ++, который я использовал для сравнения:
#include "stdafx.h"#include <chrono>
#include <iostream>
#include <omp.h>
#include <math.h>
using namespace std;
using namespace chrono;
#define DEFAULT_MAX_TESTS 16'000'000
inline int isprime( unsigned long nNumber ) {
unsigned long
i
, s = static_cast< unsigned long >( sqrt( static_cast< double >( nNumber ) ) )
;
if ( nNumber % 2 == 0 ) {
return 0;
} else {
for( i = 3; i <= s; i += 2 ) {
if ( nNumber % i == 0 ) return 0;
} // for.
return 1;
} // else.
} // isprime.
int main( ) {
const unsigned long cstnMaxTests = DEFAULT_MAX_TESTS;
unsigned long nPrimeNumbers = 0;
steady_clock::time_point start = steady_clock::now( );
for( long n = 1; n < cstnMaxTests; n += 2 ) {
nPrimeNumbers += isprime( n );
} // for.
steady_clock::time_point end = steady_clock::now( );
auto time = duration_cast< milliseconds >( end - start ).count( );
cout
<< "milliseconds: " << time
<< endl << "Number of Primes: " << nPrimeNumbers
<< endl
;
return 0;
} // main.
Вот код, который работает примерно в 4 раза быстрее, чем ваш:
module modIsPrime
export isprime, Test_isprime
@inline function isprime(nNumber)
nNumber & 1 == 0 && return 0
for i = 3:2:isqrt(nNumber)
i*unsafe_trunc(Int,nNumber/i) == nNumber && return 0
end
return 1
end
function Test_isprime()
nPrimeNumbers = 1
for n = 3:2:16000000
nPrimeNumbers += isprime(n)
end
println("Prime numbers: ", nPrimeNumbers)
end
end
Было бы неплохо увидеть сравнение времени на одной машине (у меня под рукой нет компилятора C ++). Есть небольшое исправление в Test_isprime
для правильного подсчета (результат тот же, но вы посчитали 1
как простое и 2
как составной в вашем коде).
РЕДАКТИРОВАТЬ: Я переместил расчет isqrt
после тестирования число является четным, что экономит некоторое время (но это не главное), если вы хотите честное сравнение с C ++, его также следует перенести туда.
Других решений пока нет …