2013-09-26 4 views
3

У меня довольно большой файл CSV с 4 миллионами записей с 375 полями, которые необходимо обработать. Я использую библиотеку Ruby CSV для чтения этого файла, и это очень медленно. Я думал, что обработка файлов PHP CSV была медленной, но, сравнивая два чтения, PHP более чем в 100 раз быстрее. Я не уверен, что я делаю что-то глупое, или это просто реальность того, что Ruby не оптимизирован для такого типа пакетной обработки. Я установил простые тестовые pgms, чтобы получить сравнительные времена как в Ruby, так и в PHP. Все, что я делаю, читается, не пишет, не строит большие массивы и не выходит из циклов чтения CSV после обработки 50 000 записей. Кто-нибудь еще испытал эту проблему с производительностью?Почему файл Ruby CSV читается очень медленно?

Я работаю локально на MAC с 4-х гигабайтной памятью, работает OS X 10.6.8 и Ruby 1.8.7.

Процесс Ruby занимает 497 секунд, чтобы просто читать 50 000 записей, процесс PHP работает через 4 секунды, что не является опечаткой, это более чем в 100 раз быстрее. FYI. У меня был код в циклах, чтобы распечатать данные, чтобы убедиться, что каждый из процессов фактически просматривает файлы и возвращает данные.

Это рубин Код:

require('time') 
require('csv') 
x=0 
t1=Time.new 
CSV.foreach(pathfile) do |row| 
    x += 1 
    if x > 50000 then break end 
end 
t2 = Time.new 
puts " Time to read the file was #{t2-t1} seconds" 

Вот PHP код:

$t1=time(); 
$fpiData = fopen($pathdile,'r') or die("can not open input file "); 
$seqno=0; 
while($inrec = fgetcsv($fpiData,0,',','"')) { 
    if ($seqno > 50000) break; 
    $seqno++; 
} 
fclose($fpiData) or die("can not close input data file"); 
$t2=time(); 
$t3=$t2-$t1; 
echo "Start time is $t1 - end time is $t2 - Time to Process was " . $t3 . "\n"; 
+2

В чем ваш вопрос? –

+1

Сначала обновите свой Ruby. 1.8.7 имел медленный CSV, плюс, по сравнению с сегодняшним Ruby v2.0, он медленный. –

+0

Майк, я пытаюсь выяснить, испытывает ли кто-нибудь еще эту проблему с производительностью, и если у них есть, то удалось ее решить? Как сказал Tin Man, это может быть связано с моей версией, так как кажется, что 1.8.7 имеет медленную библиотеку CSV. – Eric

ответ

5

Вы, вероятно, получить массовый прирост скорости, просто обновление до текущей версии Ruby. в версии 1.9, FasterCSV был интегрирован в стандартную библиотеку CSV Ruby.

Отъезд Chruby для управления различными версиями Ruby.

0

Я думаю, что используя CSV немного переборщик для этого.

Давным-давно я видел этот вопрос, и причина медленности Ruby заключается в том, что он загружает весь CSV-файл в память сразу. Я видел, как некоторые люди преодолевали эту проблему, используя IO class. Например, посмотрите на this gist для своего метода self.perform(url).

+2

'CSV.foreach' читает по одной строке за раз. Смотрите: http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html#label-A +Line+at+a+Time – Momer

+0

lol Я полностью забыл об этом. Я был убежден, что CSV.foreach загружает сначала все в память. –

+1

Для 1.8.7 Ruby, который использует Эрик, это может быть :) – Momer

2

Отметьте smarter_csv Gem, который имеет специальные опции для обработки огромных файлов путем чтения данных в кусках.

Он также возвращает CSV-данные как хэши, что упрощает вставку или обновление данных в базе данных.

Смежные вопросы