Подтвердить что ты не робот

Причина скорости загрузки в пакете data.table в R

Меня поражает скорость функции fread в data.table в больших файлах данных, но как это удается читать так быстро? Каковы основные различия в реализации между fread и read.csv?

4b9b3361

Ответ 1

Я полагаю, что мы сравниваем с read.csv со всеми известными советами, такими как установка colClasses, nrows и т.д. read.csv(filename) без каких-либо других аргументов, в основном потому, что сначала считывает все в память, как если бы это было character, а затем пытается принудить его к integer или numeric в качестве второго шага.

Итак, сравнивая fread с read.csv(filename, colClasses=, nrows=, etc)...

Они оба написаны на C, так что это не так.

В частности, нет одной причины, но, по существу, память fread отображает файл в память и затем выполняет итерацию через файл с помощью указателей. В то время как read.csv считывает файл в буфер через соединение.

Если вы запустите fread с помощью verbose=TRUE, он расскажет вам, как он работает и сообщит время, затраченное на каждый из шагов. Например, обратите внимание, что он пропускает прямо в середину и конец файла, чтобы лучше понять типы столбцов (хотя в этом случае верхние 5 были достаточными).

> fread("test.csv",verbose=TRUE)
Input contains no \n. Taking this to be a filename to open
File opened, filesize is 0.486 GB
File is opened and mapped ok
Detected eol as \n only (no \r afterwards), the UNIX and Mac standard.
Using line 30 to detect sep (the last non blank line in the first 'autostart') ... sep=','
Found 6 columns
First row with 6 fields occurs on line 1 (either column names or first row of data)
All the fields on line 1 are character fields. Treating as the column names.
Count of eol after first data row: 10000001
Subtracted 1 for last eol and any trailing empty lines, leaving 10000000 data rows
Type codes (   first 5 rows): 113431
Type codes (+ middle 5 rows): 113431
Type codes (+   last 5 rows): 113431
Type codes: 113431 (after applying colClasses and integer64)
Type codes: 113431 (after applying drop or select (if supplied)
Allocating 6 column slots (6 - 0 dropped)
Read 10000000 rows and 6 (of 6) columns from 0.486 GB file in 00:00:44
  13.420s ( 31%) Memory map (rerun may be quicker)
   0.000s (  0%) sep and header detection
   3.210s (  7%) Count rows (wc -l)
   0.000s (  0%) Column type detection (first, middle and last 5 rows)
   1.310s (  3%) Allocation of 10000000x6 result (xMB) in RAM
  25.580s ( 59%) Reading data
   0.000s (  0%) Allocation for type bumps (if any), including gc time if triggered
   0.000s (  0%) Coercing data already read in type bumps (if any)
   0.040s (  0%) Changing na.strings to NA
  43.560s        Total

NB: эти тайминги на моем очень медленном нетбуке без SSD. Как абсолютное, так и относительное время каждого шага будет широко варьироваться от машины к машине. Например, если вы повторно запустите fread во второй раз, вы можете заметить, что время на mmap намного меньше, потому что ваша ОС кэшировала его из предыдущего прогона.

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             AuthenticAMD
CPU family:            20
Model:                 2
Stepping:              0
CPU MHz:               800.000         # i.e. my slow netbook
BogoMIPS:              1995.01
Virtualisation:        AMD-V
L1d cache:             32K
L1i cache:             32K
L2 cache:              512K
NUMA node0 CPU(s):     0,1