Возвращает ли диапазон PHP ('A', 'Z') статический массив? - PullRequest
3 голосов
/ 18 февраля 2012

Я пропустил некоторый код, который я написал для генерации навигации A-Z на странице продукта, и метод, в котором это было сделано, был циклом for; используя ascii octals 65-91 и функцию PHP chr(). Мне стало интересно, существует ли более простой и / или более эффективный способ сделать это, и я обнаружил, что функция PHP range() поддерживает алфавитные диапазоны.

После того как я написал свой тестовый код для сравнения различных методов, на ум пришло несколько вопросов:

  1. Хранит ли PHP статический массив алфавита?
  2. Как мне сделать профиль более глубоким, чтобы посмотреть под слой PHP, чтобы увидеть что происходит?

У меня есть cachegrind скрипта PHP, который может быть присоединен при необходимости, в дополнение к конфигурации среды. Для тех, кто хочет знать спецификации машины, на которой он был выполнен, вот несколько ссылок:

root @ workbox: ~ $ lshw http://pastebin.com/cZZRjJcR

root @ workbox: ~ $ sysinfo http://pastebin.com/ihQkkPAJ

<?php
/*
 * determine which method out of 3 for returning
 * an array of uppercase alphabetic characters 
 * has the highest performance
 * 
 * +++++++++++++++++++++++++++++++++++++++++++++
 * 
 * 1) Array $alpha = for($x = 65; $x < 91; $x++) { $upperChr[] = chr($x); }
 * 2) Array $alpha = range(chr(65), chr(90);
 * 3) Array $alpha = range('A', 'Z');
 * 
 * +++++++++++++++++++++++++++++++++++++++++++++
 * 
 * test runs with iterations:
 * 
 * 10,000:
 * - 1) upperChrElapsed: 0.453785s
 * - 2) upperRangeChrElapsed: 0.069262s
 * - 3) upperRangeAZElapsed: 0.046110s
 * 
 * 100,000:
 * - 1) upperChrElapsed: 0.729015s
 * - 2) upperRangeChrElapsed: 0.078652s
 * - 3) upperRangeAZElapsed: 0.052071s
 * 
 * 1,000,000:
 * - 1) upperChrElapsed: 50.942950s
 * - 2) upperRangeChrElapsed: 10.091785s
 * - 3) upperRangeAZElapsed: 8.073058s
 */

ini_set('max_execution_time', 0);
ini_set('memory_limit', 0);

define('ITERATIONS', 1000000); // 1m loops x3

$upperChrStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperChr = array();
    for($x = 65; $x < 91; $x++) {
            $upperChr[] = chr($x);
    }
}
$upperChrElapsed = microtime(true) - $upperChrStart;

// +++++++++++++++++++++++++++++++++++++++++++++

$upperRangeChrStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperRangeChr = range(chr(65), chr(90));   
}
$upperRangeChrElapsed = microtime(true) - $upperRangeChrStart;

// +++++++++++++++++++++++++++++++++++++++++++++

$upperRangeAZStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperRangeAZ = range('A', 'Z');    
}
$upperRangeAZElapsed = microtime(true) - $upperRangeAZStart;

printf("upperChrElapsed: %f\n", $upperChrElapsed);
printf("upperRangeChrElapsed: %f\n", $upperRangeChrElapsed);
printf("upperRangeAZElapsed: %f\n", $upperRangeAZElapsed);

?>

1 Ответ

2 голосов
/ 18 февраля 2012

Не тратит ли PHP память на массив букв?Я бы сомневался в этом.range () также будет работать с самыми разными значениями.

Если производительность в таком случае является проблемой, вы можете объявить массив вне цикла, чтобы его можно было использовать повторно.Однако большой выигрыш редко достигается за счет микрооптимизации.Использование профилирования в более крупных приложениях для получения значительных результатов.

Что касается профилирования на более низком уровне, вы можете просто использовать valgrind в PHP CLI.Я также видел, как он используется в процессе Apache.

Похожие: Как профилировать мое приложение C ++ на linux

...