Одним из наиболее важных методов оптимизации скорости во многих языках является повторное использование экземпляров. В этом случае увеличение скорости происходит по крайней мере из двух факторов:
1. Меньшее количество экземпляров означает меньше времени, затрачиваемого на строительство.
2. Чем меньше объем памяти, используемой приложением, тем меньше кэш-памяти ЦП пропускает .
Для приложений, где скорость является приоритетом № 1, существует очень узкое узкое место между ЦП и ОЗУ. Одной из причин узкого места является задержка оперативной памяти.
PHP, Ruby, Python и т. Д. Связаны с промахами кэша тем, что даже они хранят в ОЗУ по крайней мере некоторые (возможно, все) данные времени выполнения интерпретируемых программ.
Строковая реализация - это одна из операций, которая выполняется довольно часто в относительно «огромных количествах», и она может оказать заметное влияние на скорость.
Вот run_test.bash эксперимента по измерению:
#!/bin/bash
for i in `seq 1 200`;
do
/usr/bin/time -p -a -o ./measuring_data.rb php5 ./string_instantiation_speedtest.php
done
Вот ./string_instantiation_speedtest.php и результаты измерений:
<?php
// The comments on the
// next 2 lines show arithmetic mean of (user time + sys time) for 200 runs.
$b_instantiate=False; // 0.1624 seconds
$b_instantiate=True; // 0.1676 seconds
// The time consumed by the reference version is about 97% of the
// time consumed by the instantiation version, but a thing to notice is
// that the loop contains at least 1, probably 2, possibly 4,
// string instantiations at the array_push line.
$ar=array();
$s='This is a string.';
$n=10000;
$s_1=NULL;
for($i=0;$i<$n;$i++) {
if($b_instantiate) {
$s_1=''.$s;
} else {
$s_1=&$s;
}
// The rand is for avoiding optimization at storage.
array_push($ar,''.rand(0,9).$s_1);
} // for
echo($ar[rand(0,$n)]."\n");
?>
Мой вывод из этого эксперимента и еще одного эксперимента, который я провел с Ruby 1.8, заключается в том, что имеет смысл передавать строковые значения по ссылке.
Один из возможных способов обеспечения возможности «передачи строк по ссылке» во всей области приложения - это постоянное создание нового экземпляра строки всякий раз, когда необходимо использовать модифицированную версию строки.
Чтобы увеличить локальность, следовательно, скорость, можно уменьшить объем памяти, который потребляет каждый из операндов. Следующий эксперимент демонстрирует случай конкатенации строк:
<?php
// The comments on the
// next 2 lines show arithmetic mean of (user time + sys time) for 200 runs.
$b_suboptimal=False; // 0.0611 seconds
$b_suboptimal=True; // 0.0785 seconds
// The time consumed by the optimal version is about 78% of the
// time consumed by the suboptimal version.
//
// The number of concatenations is the same and the resultant
// string is the same, but what differs is the "average" and maximum
// lengths of the tokens that are used for assembling the $s_whole.
$n=1000;
$s_token="This is a string with a Linux line break.\n";
$s_whole='';
if($b_suboptimal) {
for($i=0;$i<$n;$i++) {
$s_whole=$s_whole.$s_token.$i;
} // for
} else {
$i_watershed=(int)round((($n*1.0)/2),0);
$s_part_1='';
$s_part_2='';
for($i=0;$i<$i_watershed;$i++) {
$s_part_1=$s_part_1.$i.$s_token;
} // for
for($i=$i_watershed;$i<$n;$i++) {
$s_part_2=$s_part_2.$i.$s_token;
} // for
$s_whole=$s_part_1.$s_part_2;
} // else
// To circumvent possible optimization one actually "uses" the
// value of the $s_whole.
$file_handle=fopen('./it_might_have_been_a_served_HTML_page.txt','w');
fwrite($file_handle, $s_whole);
fclose($file_handle);
?>
Например, если собирать HTML-страницы, содержащие значительное количество текста, можно подумать о порядке, о том, как различные части сгенерированного HTML объединяются вместе.
BSD-лицензированная PHP-реализация и Ruby-реализация алгоритма конкатенации строк водораздела доступна. Тот же алгоритм может быть (был мной) обобщен для ускорения умножения произвольных целых чисел точности.