- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在针对特定问题开发自定义引导算法,并且由于我需要大量重复,所以我确实关心性能。对此,我对如何正确使用runif有一些疑问。我知道我可以自己运行基准测试,但 C++ 优化往往很困难,我也想了解任何差异的原因。
第一个问题:
第一个代码块比第二个快吗?
for (int i = 0; i < n_boot; i++) {
new_random = runif(n); //new_random is pre-allocated in class
// do something with the random numbers
}
for (int i = 0; i < n_boot; i++) {
NumericVector new_random = runif(n);
// do something with the random numbers
}
这可能归结为 runif 是否填充左侧,或者它是否分配并传递一个新的 NumericVector。
第二个问题:
如果两个版本都分配一个新 vector ,我可以通过在标量模式下一次生成一个随机数来改进吗?
如果您想知道,内存分配占用了我处理时间的相当大一部分。通过优化其他不必要的内存分配,我将运行时间减少了 30%,所以这很重要。
最佳答案
我设置了以下 struct
以尝试准确地表示您的场景并促进基准测试:
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
struct runif_test {
size_t runs;
size_t each;
runif_test(size_t runs, size_t each)
: runs(runs), each(each)
{}
// Your first code block
void pre_init() {
Rcpp::NumericVector v = no_init();
for (size_t i = 0; i < runs; i++) {
v = Rcpp::runif(each);
}
}
// Your second code block
void post_init() {
for (size_t i = 0; i < runs; i++) {
Rcpp::NumericVector v = Rcpp::runif(each);
}
}
// Generate 1 draw at a time
void gen_runif() {
Rcpp::NumericVector v = no_init();
for (size_t i = 0; i < runs; i++) {
std::generate_n(v.begin(), each, []() -> double {
return Rcpp::as<double>(Rcpp::runif(1));
});
}
}
// Reduce overhead of pre-allocated vector
inline Rcpp::NumericVector no_init() {
return Rcpp::NumericVector(Rcpp::no_init_vector(each));
}
};
我在其中对以下导出函数进行了基准测试:
// [[Rcpp::export]]
void do_pre(size_t runs, size_t each) {
runif_test obj(runs, each);
obj.pre_init();
}
// [[Rcpp::export]]
void do_post(size_t runs, size_t each) {
runif_test obj(runs, each);
obj.post_init();
}
// [[Rcpp::export]]
void do_gen(size_t runs, size_t each) {
runif_test obj(runs, each);
obj.gen_runif();
}
这是我得到的结果:
R> microbenchmark::microbenchmark(
do_pre(100, 10e4)
,do_post(100, 10e4)
,do_gen(100, 10e4)
,times=100L)
Unit: milliseconds
expr min lq mean median uq max neval
do_pre(100, 100000) 109.9187 125.0477 145.9918 136.3749 152.9609 337.6143 100
do_post(100, 100000) 103.1705 117.1109 132.9389 130.4482 142.7319 204.0951 100
do_gen(100, 100000) 810.5234 911.3586 1005.9438 986.8348 1062.7715 1501.2933 100
R> microbenchmark::microbenchmark(
do_pre(100, 10e5)
,do_post(100, 10e5)
,times=100L)
Unit: seconds
expr min lq mean median uq max neval
do_pre(100, 1000000) 1.355160 1.614972 1.740807 1.723704 1.815953 2.408465 100
do_post(100, 1000000) 1.198667 1.342794 1.443391 1.429150 1.519976 2.042511 100
所以,假设我解释/准确地表达了你的第二个问题,
If both versions allocate a new vector, can I improve things by generating one random number at a time in scalar mode?
使用我的 gen_runif()
成员函数,我想我们可以自信地说这不是最佳方法 - 比其他两个函数慢 7.5 倍。
更重要的是,为了解决您的第一个问题,似乎仅初始化并将新的 NumericVector
分配给 Rcpp::runif(n)< 的输出会更快一些
。我当然不是 C++ 专家,但我相信第二种方法(分配给一个新的本地对象)比第一种更快,因为 copy elision .在第二种情况下,看起来好像正在创建两个对象 - =
左侧的对象、v
和一个 ( =
右侧的临时?右值?)对象,这是 Rcpp::runif()
的结果。但实际上,编译器很可能会优化这个不必要的步骤 - 我认为我链接的文章中的这段话对此进行了解释:
When a nameless temporary, not bound to any references, would be moved or copied into an object of the same type ... the copy/move is omitted. When that temporary is constructed, it is constructed directly in the storage where it would otherwise be moved or copied to.
至少,我是这样解释结果的。希望更精通该语言的人可以确认/否认/纠正这个结论。
关于c++ - runif 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30253275/
我是 R 的新手,但文档中指出 runif(n) 返回一个 0 到 1 范围内的数字,这让我感到惊讶。 我希望 0 = 1); return a + (b - a) * u; 因此,按照设计,尽管有文
这个问题已经有答案了: Possible issue about random number generator (3 个回答) 已关闭 7 年前。 我正在编写一个轮盘赌模拟器,但我只是停留在开头。我
set.seed(1432) n_len <- 400000 jdc<- data.frame(rnd = numeric(n_len)) jdc$rnd <- runif(n_len,0,1)
我正在针对特定问题开发自定义引导算法,并且由于我需要大量重复,所以我确实关心性能。对此,我对如何正确使用runif有一些疑问。我知道我可以自己运行基准测试,但 C++ 优化往往很困难,我也想了解任何差
我需要生成一个介于上限和下限之间的随机数向量。每个数字都有自己的边界 - 因此边界也是向量。 目前我使用 for 循环执行此操作,但可能有更好的方法。 # Bounds lb <- c(1,2,3,4
我是 responding在 Reddit AskScience 提出问题我在 runif() 的功能方面遇到了一些奇怪的事情.我试图从 1 到 52 统一采样一组。我的第一个想法是使用 runif(
根据?runif,该函数不会生成最小或最大边界。我怎样才能做类似 runif 但包括最小值和最大值的事情? 这只是纯粹的理论。我想知道 - 如果我实际上需要从均匀分布中随机生成一些值(包括下限)怎么办
我试图在 R 中生成一组均匀分布的数字。我知道我们可以使用 R 中的函数“runif”来做同样的事情。但我真的很想了解如何开发此功能背后的想法。从某种意义上说,代码如何为函数“runif”工作。所以,
我试图在 R 中生成一组均匀分布的数字。我知道我们可以使用 R 中的函数“runif”来做同样的事情。但我真的很想了解如何开发此功能背后的想法。从某种意义上说,代码如何为函数“runif”工作。所以,
如果您运行如下代码: length(unique(runif(10000000))) length(unique(rnorm(10000000))) 你会看到只有大约 99.8% 的 runif 值是
你能帮我解释一下这段代码吗?我对 if_else 中的三个参数特别困惑:runif (n()) % mutate(cut = if_else(runif(n()) % ggplot() +
我正在使用 R 编程语言。我正在尝试生成 1 到 0 之间的随机整数。使用以下链接 ( http://www.cookbook-r.com/Numbers/Generating_random_numb
你能帮我解释一下这段代码吗?我对 if_else 中的三个参数特别困惑:runif (n()) % mutate(cut = if_else(runif(n()) % ggplot() +
我正在使用 R 编程语言。我正在尝试生成 1 到 0 之间的随机整数。使用以下链接 ( http://www.cookbook-r.com/Numbers/Generating_random_numb
我们在使用 R 的 runif 时,在我们的代码中遇到了一个奇怪的情况。并用 set.seed 设置种子与 kind = NULL选项(除非我弄错了,否则解析为 kind = "default" ;默
我想使用 runif 为数据表中的每一行生成一个随机数。不幸的是,我最终在每一行中得到相同的数字。 require(data.table) dx dx min max sum runi
我必须为大小为 N 的向量的两组生成随机数。 一组的概率为 p,另一组的概率为 q = 1-p。(例如,对于 p=0.5 的 1000 人,我必须从一个分布生成 500 个随机数,从另一个分布生成 5
我必须为大小为 N 的向量的两组生成随机数。 一组的概率为 p,另一组的概率为 q = 1-p。(例如,对于 p=0.5 的 1000 人,我必须从一个分布生成 500 个随机数,从另一个分布生成 5
我有一个数组(分布),我想在 a 和 b 的某个范围内进行分布,这是在 R 中使用函数 完成的qunif,我想用 Python 来做,它给出了不同的结果: R a <- c(0.012701112,
我设置了种子,生成均匀分布的随机数,用逆CDF方法得到一组正态分布的随机数。然后,我重置种子并使用 rnorm() 生成正态分布的随机数.结果是不同的。 R 中的随机数生成器不是默认使用 Mersen
我是一名优秀的程序员,十分优秀!