c++ - 使用 Rcpp 计算文件序列行数的时间量高于预期

标签 c++ r rcpp

我有一个清理文件的过程,然后将它们保存到 arrow 稍后可以读取的格式正确的文件中。这些文件采用 tsv 格式,大约有 30 列,混合数据类型 - 大部分是字符,但也有一些数字列。有大量文件只有标题而没有数据内容。我决定在读入文件进行清理之前,我会检查以确保它们具有内容,而不是作为数据帧读入文件,然后检查内容。所以,本质上,我只是想检查文件中的行数是否为 >= 2。我正在使用一个简单的 C++ 方法,使用 Rcpp 将其拉入 R 中:

Rcpp::cppFunction(
  "
  #include <fstream>
  bool more_than_one_line(std::string filepath) {
    std::ifstream input_file;
    input_file.open(filepath);
    std::string unused;
    int numLines = 0;
    while(std::getline(input_file, unused)) {
      ++numLines;
      if (numLines >= 2) {
        return true;
      }
    }
    return false;
  }
  "
)

我进行了一些计时测量,如下所示:

v <- vector(mode="numeric", length=1000)
ii = 0
for (file in listOfFiles[1:1000]) {
  print(ii)
  ii = ii + 1
  t0 <- Sys.time()
  more_than_one_line(file);
  v[ii] <- difftime(Sys.time(), t0)
}

当我运行此代码时,如果文件以前从未被读取过,则每个文件大约需要 1 秒;如果我在之前处理过的文件上运行代码,速度会快得多。然而,根据 this SO answer ,计算 12M 行文件中的行数的最快时间是 0.1 秒(我的文件最多 500k 行),并且推荐 fastest strategy 的 SO 用户(使用 Linux wc )还建议使用 C++ 会相当快。我认为我编写的 C++ 方法即使不是更快,也会与 wc 方法一样快,至少是因为我最多只阅读前两行。

我的想法是错误的吗?难道是我的方法不对?

最佳答案

在我对OP链接的问题的回答中,我提到了包fpeek,函数peek_count_lines 。这是一个用 C++ 编写的快速函数。我的计算机(运行 Windows 11 的 1 年前第 11 代 Intel(R) Core(TM) i5-1135G7 @ 2.40GHz)上有 82 个 CSV 文件的目录,行数从 4.8K 行到 108K 行不等,平均每个文件需要 0.03 秒文件获取行数。
然后,您可以在 flsize >= 2 条件下使用这些值和子集。

#path <- "my/path/omited"
fls <- list.files(path, full.names = TRUE)
# how many files
length(fls)
#> [1] 82

# range of file sizes in MB
range(file.size(fls)) / 1024L / 1024L
#> [1]  0.766923 19.999812
# total file size in MB
sum(file.size(fls)) / 1024L / 1024L
#> [1] 485.6675

# this is the main problem
t0 <- system.time(
  flsize <- sapply(fls, fpeek::peek_count_lines)
)

# the files have from 4.8K to 108K lines
range(flsize)
#> [1]   4882 108503
# how many files have more than just the header line
sum(flsize >= 2)
#> [1] 82

# timings
t0
#>    user  system elapsed 
#>    0.28    1.12    2.30
# average timings per file
t0/length(flsize)
#>        user      system     elapsed 
#> 0.003414634 0.013658537 0.028048780

创建于 2023-02-04,使用 reprex v2.0.2

关于c++ - 使用 Rcpp 计算文件序列行数的时间量高于预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75342573/

相关文章:

c++ - g++ 使用虚拟继承的简单程序的汇编输出

c++ - 分析在 I/O C++ 中花费的时间

c++ - 链表语法 : is "next" already defined?

R read.csv "More columns than column names"错误

r 如何使用这些约束重新调整一系列数字?

C++ 和 R 接口(interface),获取输出

c++ - 多平台原子增量

r - 如何用 R 中的分类标签替换数据框中的数值?

string - Rcpp CharacterVector:为什么单个元素不是 std::strings?

r - 将 'const Rcpp::CharacterVector&' 的元素转换为 'std::string'