代码之家  ›  专栏  ›  技术社区  ›  Alberto

Julia绩效建议

  •  1
  • Alberto  · 技术社区  · 7 年前

    为了比较Julia和C/C++的性能,我编写了一个非常简单的程序。基本上,它返回的总质数小于给定的数。问题是,我得到的平均时间比c/c++等效时间差2.5倍(好吧,应该接近1.0倍)。我使用Julia0.5.0(但是,我也在0.6.0上进行了测试,得到了相同的结果)。我发现 % 对于 mod 进行模数运算有帮助。此外,在任何地方设置类型都会给我带来一些好处。

    有人能帮我找出在这个例子中我还缺少什么来提高Julias的性能吗?提前谢谢。

        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
    

    编辑-正如Ron提到的,下面是我用来进行比较的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.
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Bogumił Kamiński    7 年前

    以下是一些比您的速度快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++进行公平的比较,也应该将其移到那里。