Pythonには、次の簡単なコードがあります。
N = 10000
mu = 0.0001
iterations = 10000
l = 10
@nb.njit()
def func1(N, l, mu, iterations):
intList = [0]*N
for x in range(iterations):
for number in range(N):
for position in range(l):
if random.random() < mu:
intList[number] = intList[number] ^ (1 << position)
func1(N, l, mu, iterations)
count = 1
print(timeit(lambda: func1(N, l, mu, iterations), number=count))
>>> 5.677
私はC ++に慣れていませんが、Pythonバージョンと比較してどれだけ速いかを知りたかったのです。私のPythonコードは非常に単純なので、試してみることができると思いました。Pythonコードと同等であるはずの私のC ++コードは
#include <iostream>
#include <random>
using namespace std;
int func1(int iterations, int l, int N, float mu)
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_real_distribution<> dis(0.0, 1.0);
std::vector<int> intList(N);
//for (int i = 0; i < N; i++)
// cout << intList[i];
//cout << "\n";
int x, number, position;
for (x = 0; x < iterations; x++) {
for (number = 0; number < N; number++) {
for (position = 0; position < l; position++) {
if (dis(gen) < mu) {
intList[number] = intList[number] ^ (1 << position);
}
}
}
}
//for (int i = 0; i < N; i++)
// cout << intList[i];
return 0;
}
int main()
{
int N, l, iterations;
float mu;
N = 10000;
mu = 0.0001;
iterations = 10000;
l = 10;
func1(iterations, l, N, mu);
cout << "\nFertig";
}
ただし、このコードには最大5〜10倍の時間がかかります。本当にびっくりしました。その説明は何ですか?
Numbaは、呼び出しを独自のインライン化された内部MersenneTwister実装に内部的に変換しrandom.random
ます。したがって、効果的に全体がLLVMによって効率的なコードにコンパイルされます。他の実装と同様に、C ++で記述されている可能性もあります。func1
したがって、最適化をオンにしてC ++実装をコンパイルすると、問題を再現できないのは当然のことです。両方の実装は本質的に同じです。私のマシンでは、Pythonコードは約6.1秒で実行され、C ++コードは約6.9秒で実行されます。
ただし、より速く進みたい場合は、突然変異の確率が低い遺伝子突然変異を効率的に実装したい場合は(そう思われます)、最初に確率μの二項分布を生成してから、その数のインデックスを選択することをお勧めします。あなたのゲノムの長さからの置き換えなし。あるいは、ここで説明する方法です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加