Rcpp 子集连续 StringVector
Rcpp subsetting contiguous StringVector
下午好,
在使用 Rcpp 时,我一直在尝试使用类似的方法在 R 中对 x[200:300]
进行子集化。 (注意,这不是我要解决的问题,但我需要在我试图用 C++ 编写的函数中划分许多范围,我发现这是我性能的瓶颈)
然而,尽管我已经尝试使用 rcpp 中的方法,使用迭代器或其他东西,但我似乎没有找到最低限度的解决方案 "fast." 我找到的大多数解决方案都很慢.
并且查看 Rcpp 的参考资料,我似乎找不到任何东西,我在 StackExchange 中也找不到它。
我知道这段代码现在很难看...但我就是一无所知
// [[Rcpp::export]]
StringVector range_test_( StringVector& x, int i, int j){
StringVector vect(x.begin()+i, x.begin()+j);
return vect;
}
然后,速度慢了 800 倍。我一直试图在 rcpp 基础中找到与 R 相同的 x[i:j]
函数,它非常快......但我找不到它。
tests_range <- rbenchmark::benchmark(
x[200:3000],
range_test_(x, 200, 3000),
order = NULL,
replications = 80
)[,1:4]
给出结果
test replications elapsed relative
1 x[200:3000] 80 0.001 1
3 range_test_(x, 200, 3000) 80 0.822 822
如果有人知道如何在 Rcpp 中访问子集函数 x[i:j]
或类似的东西,我将不胜感激。我似乎找不到我缺少的工具。
问题是迭代器构造函数创建了一个副本。参见 this page
Copy the data between iterators first and last to the created vector
不过,您可以试试这个
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::StringVector in_range(Rcpp::StringVector &x, int i, int j) {
return x[Rcpp::Range(i - 1, j - 1)]; // zero indexed
}
用的时间更近了
> set.seed(20597458)
> x <- replicate(1e3, paste0(sample(LETTERS, 5), collapse = ""))
> head(x)
[1] "NHVFQ" "XMEOF" "DABUT" "XKTAZ" "NQXZL" "NPJLM"
>
> stopifnot(all.equal(in_range(x, 100, 200), x[100:200]))
>
> library(microbenchmark)
> microbenchmark(in_range(x, 100, 200), x[100:200], times = 1e4)
Unit: nanoseconds
expr min lq mean median uq max neval
in_range(x, 100, 200) 1185 1580 3669.780 1581 1976 3263205 10000
x[100:200] 790 790 1658.571 1185 1186 2331256 10000
请注意,有一个 page here 关于 susbetting。我在那里找不到相关的例子。
下午好,
在使用 Rcpp 时,我一直在尝试使用类似的方法在 R 中对 x[200:300]
进行子集化。 (注意,这不是我要解决的问题,但我需要在我试图用 C++ 编写的函数中划分许多范围,我发现这是我性能的瓶颈)
然而,尽管我已经尝试使用 rcpp 中的方法,使用迭代器或其他东西,但我似乎没有找到最低限度的解决方案 "fast." 我找到的大多数解决方案都很慢.
并且查看 Rcpp 的参考资料,我似乎找不到任何东西,我在 StackExchange 中也找不到它。
我知道这段代码现在很难看...但我就是一无所知
// [[Rcpp::export]]
StringVector range_test_( StringVector& x, int i, int j){
StringVector vect(x.begin()+i, x.begin()+j);
return vect;
}
然后,速度慢了 800 倍。我一直试图在 rcpp 基础中找到与 R 相同的 x[i:j]
函数,它非常快......但我找不到它。
tests_range <- rbenchmark::benchmark(
x[200:3000],
range_test_(x, 200, 3000),
order = NULL,
replications = 80
)[,1:4]
给出结果
test replications elapsed relative
1 x[200:3000] 80 0.001 1
3 range_test_(x, 200, 3000) 80 0.822 822
如果有人知道如何在 Rcpp 中访问子集函数 x[i:j]
或类似的东西,我将不胜感激。我似乎找不到我缺少的工具。
问题是迭代器构造函数创建了一个副本。参见 this page
Copy the data between iterators first and last to the created vector
不过,您可以试试这个
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::StringVector in_range(Rcpp::StringVector &x, int i, int j) {
return x[Rcpp::Range(i - 1, j - 1)]; // zero indexed
}
用的时间更近了
> set.seed(20597458)
> x <- replicate(1e3, paste0(sample(LETTERS, 5), collapse = ""))
> head(x)
[1] "NHVFQ" "XMEOF" "DABUT" "XKTAZ" "NQXZL" "NPJLM"
>
> stopifnot(all.equal(in_range(x, 100, 200), x[100:200]))
>
> library(microbenchmark)
> microbenchmark(in_range(x, 100, 200), x[100:200], times = 1e4)
Unit: nanoseconds
expr min lq mean median uq max neval
in_range(x, 100, 200) 1185 1580 3669.780 1581 1976 3263205 10000
x[100:200] 790 790 1658.571 1185 1186 2331256 10000
请注意,有一个 page here 关于 susbetting。我在那里找不到相关的例子。