[英]What is the most efficient way to generate random strings in C++?
我需要有效地生成隨機字符串。 在下文中,您將看到我的第一次嘗試。 我用 gcc 和 -O3 優化級別編譯了代碼。 生成 10^7 個長度為 64 的隨機字符串需要18.5 秒:
#include <iostream>
#include <random>
#include <algorithm>
std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
std::string rand_str (int length) {
std::string output (chars);
std::shuffle(output.begin(), output.end(), generator);
return output.substr(0, length);
}
int main() {
std::string str;
for (long i=0; i<10000000; ++i)
str = rand_str (64);
}
我檢查了 c++17 中的std::sample
,它並不比上述方法快。 此外,它不會改變字符的順序,因此它不是真正隨機的。
編輯: std::shuffle
不是一個好的選擇,因為它不允許重復。 根據評論,我修改了代碼。 這次 10^7 個隨機數需要9 多分鍾。
std::string rand_str (size_t length) {
const size_t char_size = chars.size();
std::uniform_int_distribution<> random_int (0, char_size - 1);
std::string output;
for (size_t i=0; i<length; ++i)
output.push_back(chars[random_int(generator)]);
return output;
}
我感謝任何改進代碼的建議。
#include <iostream>
#include <random>
#include <algorithm>
#include <chrono>
std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
std::string rand_str(int length) {
std::string output;
output.reserve(length);
while(length>0)
{
auto randNumb = generator();
while(randNumb > 93 && length--)
{
output.push_back(chars[randNumb%93]);
randNumb/=93;
}
}
return output;
}
int main() {
auto startTP = std::chrono::system_clock::now();
std::string rand_bytes;
for (long i=0; i<10000000; ++i)
rand_bytes = std::move(rand_str(64));
auto endTP = std::chrono::system_clock::now();
std::cout << "This took: " << std::chrono::duration_cast<std::chrono::microseconds>(endTP-startTP).count() << std::endl;
}
這在我的機器上大約需要 3 秒。 訣竅是盡可能少地調用隨機數生成器,並且只分配一次 memory。
我正在做的是將 randNumber 從基數 10 轉換為基數 93(字符的長度)。 之后,我使用每個基數 93 位作為不同的隨機數。 這為每個生成的隨機數提供了大約 5 個數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.