[Moscow.pm] Сложить 5000000 чисел

Ruslan Zakirov ruslan.zakirov на gmail.com
Вт Янв 12 09:51:32 PST 2010


2010/1/12 Alex Kapranoff <kapranoff на gmail.com>:
> 2010/1/11 Ruslan Zakirov <ruslan.zakirov на gmail.com>:
>> Последний вариант. Отдельное префиксное индексирование чуть быстрее.
>
> В нём ошибка, из-за которой всё работает на целых 25% быстрее, но неправильно :)
>
>> Попробовал splice, но он медленнее
>>
>> undef $/; @file = split ' ', scalar <>;
>>
>> $res = '';
>> for (1 .. shift(@file)) {
>>    $rows = $file[$cur++];
>>
>>    @s = (0) x ($rows + 1);
>>    for (0 .. $rows-1) {
>>        $i = 0; $y = 0;
>>        $cur += $_;
>>
>>        for ($cur .. $cur+$_) {
>>            $x = $y;
>>            $y = $s[$i];
>>            $s[$i] = $file[$cur] + ($x > $y? $x : $y);
>
> Вот тут должно было $file[$_]. Использование $cur реально всё
> ускоряет. Это означает, что либо у нас оптимизатор умеет вычислять
> неизменяющиеся выражения перед циклом, либо срабатывает эффект
> процессорного кэша.

Бывает. Я думаю, что есть несколько реальных способов улучшить немного perl.

1) По идее use integer; должен ускорять все это дело. Под действием
прагмы используются pp_i_add и соответственно другие макросы получения
чисел, но как-то разницы в скорости я не заметил, хотя на 5М должно
быть. Похоже на баг или какой-то сторонний эфект, например какая-то
операция генерит float/double, а потом обратно.
2) Я не увидел в splice оптимизации под случаи, когда из массива
только вырезаются элементы с края. В таких случаях perl может избежать
переноса элементов, а только манипулировать окном. Конечно спорный
момент, но можно попробовать как-то поиграться.

-- 
Best regards, Ruslan.


Подробная информация о списке рассылки Moscow-pm