什么更快?
random() % 100;
或
static_cast<int>((random() / 4294967296) * 100);
我真的不知道如何正确地进行基准测试,并且在我的计算机上更快出现的结果在其他计算机上可能无法正常工作,因此我就谦虚地向Stackoverflow上的智者提出这个问题
答案 0 :(得分:4)
可以使用rand()
或std::mt19997
完成随机数的生成。后者是首选,我仍将这两种情况作为基准。 (Visual Studio 2017社区x64)。我使用了一个虚拟变量,因此编译器无法忽略随机生成语句。 rand()
返回int
,而std::mt19937
返回std::uint32_t
。因此,为了减少转换次数,我使用了2个虚拟变量。
#include <iostream>
#include <random>
#include <chrono>
#include <limits>
#include <string>
#include <cstdlib>
namespace util {
constexpr std::size_t loop{ 10'000'000u };
std::mt19937 engine{ std::random_device{}() };
int rand_dummy{ 0 };
std::uint32_t mt19937_dummy{ 0u };
}
void rand_mod() {
for (std::size_t i = 0u; i < util::loop; ++i) {
util::rand_dummy = (rand() % 100);
}
}
void rand_div() {
for (std::size_t i = 0u; i < util::loop; ++i) {
util::rand_dummy = static_cast<int>(static_cast<double>(rand()) / RAND_MAX * 100);
}
}
void mt19937_mod() {
for (std::size_t i = 0u; i < util::loop; ++i) {
util::mt19937_dummy = (util::engine() % 100u);
}
}
void mt19937_div() {
for (std::size_t i = 0u; i < util::loop; ++i) {
util::mt19937_dummy = static_cast<std::uint32_t>(static_cast<double>(util::engine()) / std::numeric_limits<std::uint32_t>::max() * 100u);
}
}
void benchmark(void(*f)(void), const std::string& name) {
auto t1 = std::chrono::high_resolution_clock::now();
f();
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << name << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count() / 1e6 << "ms\n";
}
int main() {
srand(std::random_device{}());
benchmark(rand_mod, "rand() | mod: ");
benchmark(rand_div, "rand() | div: ");
std::cout << "---------------------------\n";
benchmark(mt19937_mod, "std::mt19937 | mod: ");
benchmark(mt19937_div, "std::mt19937 | div: ");
return util::rand_dummy + util::mt19937_dummy;
}
禁用优化(/ Od):
rand() | mod: 956.128ms
rand() | div: 796.235ms
---------------------------
std::mt19937 | mod: 437.885ms
std::mt19937 | div: 584.477ms
全面优化(/ Ox):
rand() | mod: 276.092ms
rand() | div: 262.224ms
---------------------------
std::mt19937 | mod: 61.4312ms
std::mt19937 | div: 103.38ms
std::mt19937
在两种情况下都更快
用于std::mt19937
取模胜于除法
rand()
的分部胜过模数
所以这取决于您使用哪一个。由于std::mt19937
优于rand()
,因此答案应该是:模数比除法快。
> why rand()
is considered harmful >
请注意,您也不应该这样做:
engine() % 100;
使用std::uniform_int_distribiution(0, 99)(engine);
[{engine
是std::mt19937
]