您好我有一个std::vector<std::string>
,其中包含2011-03-23T12:23:32.123
这样的日期时间,我希望生成int
20110323
和122332123
的2个向量。< / p>
我正在使用一个名为Rcpp的C++
库(我认为这不是问题,但你永远不会知道,所以我放了Rcpp
标签)
我这样做是为了完成这项工作,但这很慢,我怎样才能加快速度呢?
Rcpp::List datetimeToInt(vector<string> datetimes){
const int N=datetimes.size();
Rcpp::IntegerVector date(N); //please consider those as std::vector<int>
Rcpp::IntegerVector time(N);
//this is what I want to speed up
for(int i=0; i<N; ++i){
datetimes[i].erase(std::remove_if(datetimes[i].begin(), datetimes[i].end(), not1(ptr_fun(::isdigit))), datetimes[i].end());
date[i] = atoi(datetimes[i].substr(0,8).c_str());
time[i] = atoi(datetimes[i].substr(8,12).c_str());
}
return Rcpp::List::create(_["date"]=date, _["time"]=time);
}
答案 0 :(得分:1)
您的代码非常优秀,您可以做的唯一更改就是替换此部分
datetimes[i].erase(std::remove_if(datetimes[i].begin(), datetimes[i].end(), not1(ptr_fun(::isdigit))), datetimes[i].end());
date[i] = atoi(datetimes[i].substr(0,8).c_str());
time[i] = atoi(datetimes[i].substr(8,12).c_str());
使用更复杂和优化的东西,例如像这样的smt(但我没有测试它):
int dateId = 0;
int timeId = 0;
char time_c[9];
char date_c[8];
for (int strId = 0; i < str.length(); ++strId) {
if (isdigit(datetimes[i][strId]) {
if (dateId >= 8) {
time_c[timeId] = datetimes[i][strId];
++timeId;
} else {
date_c[dateId] = datetimes[i][strId];
++dateId;
}
}
}
date[i] = atoi(date_c);
time[i] = atoi(time_c);
它只在一次传递中将你的字符串分成两部分
答案 1 :(得分:1)
使用std::vector<std::string>
,我们必须复制字符串。这是浪费时间。您应该使用CharacterVector
,在您直接处理数据时不需要复制。
// [[Rcpp::export]]
List datetimeToInt2(CharacterVector datetimes){
const int N=datetimes.size();
IntegerVector date(N);
IntegerVector time(N);
std::string current ;
//this is what I want to speed up
for(int i=0; i<N; ++i){
current = datetimes[i] ;
current.erase(std::remove_if(current.begin(), current.end(), std::not1(std::ptr_fun(::isdigit))), current.end());
date[i] = atoi(current.substr(0,8).c_str());
time[i] = atoi(current.substr(8,12).c_str());
}
return List::create(_["date"]=date, _["time"]=time);
}
让我们衡量一下:
> dates <- rep("2011-03-23T12:23:32.123", 1e+05)
> system.time(res1 <- datetimeToInt(dates))
user system elapsed
0.081 0.006 0.087
> system.time(res2 <- datetimeToInt2(dates))
user system elapsed
0.044 0.000 0.044
> identical(res1, res2)
[1] TRUE
答案 2 :(得分:1)
您可能希望查看Simon的fasttime
包(可用here on rforge.net),该包具有非常相似的功能。
它使用字符串操作并且没有日期解析来分割ISO日期时间字符串(尽管使用“T”分隔符),假定为UTC时间。我一直使用它,因为它符合我的需要。
作为一个注释,您可能需要更仔细地考虑何时使用STL容器以及何时使用Rcpp容器。
最后,当你可以使用R,C ++和Rcpp所拥有的正确日期类型时,不要使用string或int进行日期算术或比较。