Unverified Commit 9a0e13ac authored by Da Zheng's avatar Da Zheng Committed by GitHub
Browse files

Speed up random number generation. (#2953)



* speed up random number generation.

* fix lint.

* Fix

* fix.
Co-authored-by: default avatarZheng <dzzhen@3c22fba32af5.ant.amazon.com>
parent b8b0fd22
...@@ -100,12 +100,23 @@ void RandomEngine::UniformChoice(IdxType num, IdxType population, IdxType* out, ...@@ -100,12 +100,23 @@ void RandomEngine::UniformChoice(IdxType num, IdxType population, IdxType* out,
} }
} else { } else {
// reservoir algorithm // In this case, `num >= population / 10`. To reduce the computation overhead,
// time: O(population), space: O(num) // we should reduce the number of random number generations. Even though
for (IdxType i = 0; i < num; ++i) out[i] = i; // reservior algorithm is more memory effficient (it has O(num) memory complexity),
for (IdxType i = num; i < population; ++i) { // it generates O(population) random numbers, which is computationally expensive.
const IdxType j = RandInt(i + 1); // This algorithm has memory complexity of O(population) but generates much fewer random
if (j < num) out[j] = i; // numbers O(num). In the case of `num >= population/10`, we don't need to worry about
// memory complexity because `num` is usually small. So is `population`. Allocating a small
// piece of memory is very efficient.
std::vector<IdxType> seq(population);
for (size_t i = 0; i < seq.size(); i++) seq[i] = i;
for (IdxType i = 0; i < num; i++) {
IdxType j = RandInt(i, population);
std::swap(seq[i], seq[j]);
}
// Save the randomly sampled numbers.
for (IdxType i = 0; i < num; i++) {
out[i] = seq[i];
} }
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment