read.csv比data.table :: fread更快

时间:2018-08-09 11:08:45

标签: r dataframe data.table fread

在网络上我可以读到我应该使用data.table并读取来加载我的数据。

但是当我运行基准测试时,我会得到以下结果

Unit: milliseconds
expr       min        lq      mean    median        uq        max neval
test1  1.229782  1.280000  1.382249  1.366277  1.460483   1.580176    10
test3  1.294726  1.355139  1.765871  1.391576  1.542041   4.770357    10
test2 23.115503 23.345451 42.307979 25.492186 57.772522 125.941734    10

下面显示了代码。

loadpath <- readRDS("paths.rds")

microbenchmark(
  test1 = read.csv(paste0(loadpath,"data.csv"),header=TRUE,sep=";", stringsAsFactors = FALSE,colClasses = "character"),
  test2 = data.table::fread(paste0(loadpath,"data.csv"), sep=";"),
  test3 = read.csv(paste0(loadpath,"data.csv")),
  times = 10
) %>%
  print(order = "min") 

我知道fread()应该比read.csv()更快,因为它会尝试先将行作为字符读取到内存中,然后尝试将它们转换为数据类型的整数和因数。另一方面,fread()只是将所有内容读取为字符。

如果是这样,test2是否应该比test3快?

有人可以向我解释一下,为什么我不加速使用test2或与test1保持相同的速度吗? :)

2 个答案:

答案 0 :(得分:11)

如果您考虑使用较大的文件,则

data.table::fread的显着性能优势将变得显而易见。这是一个完全可重现的示例。

  1. 让我们生成一个由10 ^ 5行和100列组成的CSV文件

    if (!file.exists("test.csv")) {
        set.seed(2017)
        df <- as.data.frame(matrix(runif(10^5 * 100), nrow = 10^5))
        write.csv(df, "test.csv", quote = F)
    }
    
  2. 我们进行了microbenchmark分析(请注意,这可能需要几分钟的时间,具体取决于您的硬件)

    library(microbenchmark)
    res <- microbenchmark(
        read.csv = read.csv("test.csv", header = TRUE, stringsAsFactors = FALSE, colClasses = "numeric"),
        fread = data.table::fread("test.csv", sep = ",", stringsAsFactors = FALSE, colClasses = "numeric"),
        times = 10)
    res
    #          Unit: milliseconds
    #     expr        min         lq       mean     median         uq        max
    # read.csv 17034.2886 17669.8653 19369.1286 18537.7057 20433.4933 23459.4308
    #    fread   287.1108   311.6304   432.8106   356.6992   460.6167   888.6531
    
    
    library(ggplot2)
    autoplot(res)
    

enter image description here

答案 1 :(得分:-5)

如果您查看这些函数,可以发现fread比read.csv做更多的检查。如果您正在读取的文件较小,则与实际读取相比,我需要花费更多时间进行检查和准备读取。

data.table对于大型数据集来说要快得多。