Вопрос по r, fread, data.table, performance – Причина скорости фреда в пакете data.table в R

18

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

Ваш Ответ

1   ответ
28

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

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

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

Особой причины нет, но, по сути,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
Для записи @ комментарий Сандипа немного устарел, как сейчасfread поддерживаетencoding аргумент MichaelChirico
Такжеread.csv() читает все в большую символьную матрицу, а затем изменяет это, делаетfread() сделать то же самое? Вfastread мы угадываем типы столбцов, а затем приводим их к действию, чтобы избежать полной копии df. hadley
@hadley Почему ты пишешь "(нам!)"? Что вы говорите, создает полный символьный вектор? Являются претензиямиfread не принуждает как идет? Matt Dowle
Очевидно для нас! = Очевидно для всех! = Правильно. Я не предлагаю ничего оfread(). hadley

Похожие вопросы