Я сделал следующий Perl-скрипт для выполнения некоторых манипуляций с файлами на работе, но в данный момент он работает слишком медленно, чтобы его можно было запустить в производство.
Я не очень хорошо знаю Perl (не один из моих языков), поэтому может ли кто-нибудь помочь мне определить и заменить части этого скрипта, которые будут медленными, учитывая, что он обрабатывает ~ 40 миллионов строк?
Данные, передаваемые по конвейеру, имеют формат:
col1|^|col2|^|col3|!|
col1|^|col2|^|col3|!|
... 40 million of these.
Массив date_cols вычисляется перед этой частью скрипта и в основном содержит индекс столбцов, содержащих даты в предварительно преобразованном формате.
Вот часть скрипта, которая будет выполняться для каждой входной строки. Я немного подчистил его и добавил комментарии, но дайте мне знать, если что-то еще понадобится:
## Read from STDIN until no more lines are arailable.
while (<STDIN>)
{
## Split by field delimiter
my @fields = split('\|\^\|', $_, -1);
## Remove the terminating delimiter from the final field so it doesn't
## interfere with date processing.
$fields[-1] = (split('\|!\|', $fields[-1], -1))[0];
## Cycle through all column numbres in date_cols and convert date
## to yyyymmdd
foreach $col (@date_cols)
{
if ($fields[$col] ne "")
{
$fields[$col] = formatTime($fields[$col]);
}
}
print(join('This is an unprintable ASCII control code', @fields), "\n");
}
## Format the input time to yyyymmdd from 'Dec 26 2012 12:00AM' like format.
sub formatTime($)
{
my $col = shift;
if (substr($col, 4, 1) eq " ") {
substr($col, 4, 1) = "0";
}
return substr($col, 7, 4).$months{substr($col, 0, 3)}.substr($col, 4, 2);
}
csplit
? - person matchew   schedule 26.09.2012print
будет самой медленной из показанных, но я предполагаю, что она предназначена только для целей отладки. Если вы запустите именно этот код (за вычетомprint
), он все еще будет медленным? Я немного подозреваю, потому что сабвуферtrim
нигде не используется. - person dan1111   schedule 26.09.2012split
вы можете установить$/
(разделитель входных записей) на"|!|\n"
вне цикла иchomp
после каждогоreadline
/<STDIN>
. Это перемещает больше функциональности в библиотеку C (скорость!) и позволяет избежать создания анонимного массива. Попробуйте провести бенчмаркинг. - person amon   schedule 26.09.2012