는 메모리에 새로운 변수를 생성합니까?
입력 개체가 실제로 숫자 벡터 (REALSXP
)이고 단순히 반환하는 경우 (예 : as<NumericVector>(input)
이면 추가 변수가 생성되지 않습니다. 다른 경우에는 물론 새로운 메모리가 반환 된 객체에 할당되어야합니다. 예를 들어,
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector demo(RObject x) {
if (x.sexp_type() == REALSXP) {
return as<NumericVector>(x);
}
return NumericVector::create();
}
/*** R
y <- rnorm(3)
z <- letters[1:3]
data.table::address(y)
# [1] "0x6828398"
data.table::address(demo(y))
# [1] "0x6828398"
data.table::address(z)
# [1] "0x68286f8"
data.table::address(demo(z))
# [1] "0x5c7eea0"
*/
나는 그것을 할 수있는 더 좋은 방법이 있는지 알고 싶습니다.
먼저 "더 나은"정의해야
- 빠른?
- 적은 메모리를 사용합니까?
- 몇 줄의 코드가 필요합니까?
- 더 관용적입니까?
개인적으로, 나는 종종 하나 이상의 다른 것들을 수반하기 때문에 개인적으로 마지막 정의부터 시작하겠다. 예를 들어,이 접근 방식에서 우리는
- 아니라 로컬
- 에 의해 결정되는 문자를 제거하기 위해 erase-remove idiom를 사용하는 다른 함수 객체를 정의이를 구현하는 것보다 표준 라이브러리 함수
isdigit
에 의존하는 함수 객체 Predicate
정의 Predicate
; STRSXP
std::vector<std::string>
- 통화
std::transform
로 변환 - as
계산기 - 필요한 경우,
- 는 Rcpp 관용구를 사용합니다 (대신에게 자신을 구현하기 위해 노력하는, 다시)를
double
에 남아있는 것을 변환 std::atoi
를 사용 결과 벡터에이를 변환하는
#include <Rcpp.h>
using namespace Rcpp;
struct Predicate {
bool operator()(char c) const
{ return !(c == '.' || std::isdigit(c)); }
};
struct Converter {
double operator()(std::string s) const {
s.erase(
std::remove_if(s.begin(), s.end(), Predicate()),
s.end()
);
return s.empty() ? NA_REAL : std::atof(s.c_str());
}
};
// [[Rcpp::export]]
NumericVector convert(RObject obj) {
if (obj.sexp_type() == REALSXP) {
return as<NumericVector>(obj);
}
if (obj.sexp_type() != STRSXP) {
return NumericVector::create();
}
std::vector<std::string> x = as<std::vector<std::string> >(obj);
NumericVector res(x.size(), NA_REAL);
std::transform(x.begin(), x.end(), res.begin(), Converter());
return res;
}
테 최소한의 기능이 고통,
x <- c("123 4", "abc 1567.35 def", "abcdef", "")
convert(x)
# [1] 1234.00 1567.35 NA NA
(y <- rnorm(3))
# [1] 1.04201552 -0.08965042 -0.88236960
convert(y)
# [1] 1.04201552 -0.08965042 -0.88236960
convert(list())
# numeric(0)
이 뭔가 노련한 C 또는 C++ 프로그래머가 손을 쓴만큼 성능이 좋은 것인가? 거의 확실하지 않습니다. 그러나 우리는 라이브러리 함수와 일반적인 관용구를 사용했기 때문에 합리적으로 간결하며 버그가 없을 가능성이 높으며 의도는 간략하게도 분명합니다.에이 더 필요한 경우 최적화가 이루어질 수는 있지만 벤치마킹 및 프로파일 링을 먼저 수행 할 필요는 없습니다.
먼저 'dput (data_set_here)'를 사용하여 데이터 샘플을 추가하십시오. 둘째, 그렇습니다. 타입이'NumericVector'가 아닌 경우 새로운 메모리 벡터를 할당하려고합니다. – coatless