Производительность PHP: если против - PullRequest
2 голосов
/ 25 февраля 2011

Я нашел похожий вопрос здесь: Производительность: тестирование условий и присвоение

Этот вопрос не об оптимизации. Речь идет о настройках кодирования.

Вот пример:

У меня есть данные, которые я не могу контролировать. Это от третьего лица в виде строк из таблицы БД. Это результат MSSQL SP. Будучи раздутым, я хотел бы уменьшить его размер, прежде чем передавать данные по проводам в формате JSON. Я могу сделать его примерно на 80% меньше, так как большая часть данных повторяется.

Итак, я делаю что-то вроде этого:

    $processed = array();
    foreach ($result as $row)
    {
        $id = $row['id'];
        $processed[$id]['title'] = $row['title'];
        $processed[$id]['data'] = $row['data'];
        $processed[$id]['stuff'] = $row['stuff'];
        /* many more assignments with different keys */

        $unique = array();
        $unique['cost'] = $row['cost'];
        /* a few more assignments with different keys */

        $processed[$id]['prices'][$row['date']] = $unique;
    }

Я думал, что это может быть быстрее, но выглядит медленнее (я рассчитал время):

    $processed = array();
    $id = null;
    foreach ($result as $row)
    {
        if ($id != $row['id'])
        {
             $id = $row['id'];
             $processed[$id]['title'] = $row['title'];
             $processed[$id]['data'] = $row['data'];
             $processed[$id]['stuff'] = $row['stuff'];
             /* many more similar lines */
        }

        $unique = array();
        $unique['cost'] = $row['cost'];
        /* a few more similar lines */

        $processed[$id]['prices'][$row['date']] = $unique;
    }

Может ли кто-нибудь подтвердить, что с помощью PHP «if» или условные выражения действительно требуют больше вычислительных ресурсов, чем назначения? Спасибо.

[Мой ответ как правка]

Я провел несколько автономных тестов (без учета реальных данных или другого кода) на FastCGI PHP, работающем с IIS:

function testif()
{
    $i = 0;
    while ($i < 100000000)
    {
        if (1 != 0)  /* do nothing */;
        $i++;
    }

    return "done";
}

1й прогон: 20,7496500015256748 сек.

2й прогон: 20,8813898563381191 сек.

function testassign()
{
    $i = 0;
    while ($i < 100000000)
    {
        $x = "a 26 character long string";
        $i++;
    }

    return "done";
}

1й прогон: 21.0238358974455215 сек.

2й прогон: 20,7978239059451699 с.

Ответы [ 3 ]

4 голосов
/ 25 февраля 2011

Что ж, по сравнению с временем, необходимым для передачи этих данных JSON клиенту , такая разница действительно будет каплей в океане.
Черт, даже JSON-кодирование само по себе будет выполнять такие if-s и назначения тысячами при кодировании ваших данных! Проведение тестов для сравнения этих вопросов - это то, что вы делаете неправильно.

Это необычайно ограниченная точка зрения , которая приводит к таким вопросам.
Хотя задействованы миллионы других «циклов ЦП», разница в тысячи не изменится.

  • есть веб-сервер, который обрабатывает ваш запрос
  • есть интерпретатор php (который по умолчанию должен анализировать весь ваш код, выбирая его символ за символом)
  • есть поиск в базе данных, который должен обрабатывать гигабайты данных
  • задержка в сети.

Итак, чтобы провести адекватное сравнение, нужно включить все эти вещества в свои испытания. И начинайте беспокоиться, только если реальный тест покажет какую-то разницу. В противном случае это будет полная и целая трата времени.

Подобные вопросы - одна из самых страшных вещей в нашем бедном PHP-сообществе.
Нет ничего плохого в том, что касается производительности. Но нет ничего хуже, чем такой вопрос «что быстрее», прямо с головы.

И "это просто теоретический вопрос!" это не оправдание. эти вопросы никогда не носят теоретического характера, будьте честны с самим собой. Тот, кто ДЕЙСТВИТЕЛЬНО интересуется всеми мелочами, идет другим путем - имеет дело с источниками, отладчиками и профилировщиками, а не с глупыми тестами «миллиард итераций ничего».

Тот, кто действительно обеспокоен скоростью, сначала делает измерения. Такое измерение называется «профилирование» и имеет цель найти узкое место - вопрос, который ДЕЙСТВИТЕЛЬНО замедляет ваше приложение.

Тем не менее, иногда не требуются сложные измерения, а требуется лишь немного думать.
например, если у вас слишком много повторяющихся данных - стесняйтесь не просить вашу базу данных сначала вернуть меньший набор данных?

1 голос
/ 25 февраля 2011

Как я уже писал в качестве комментария к первому сообщению:

Не связано с «производительностью: если присваивание», но одним из способов сделать текстовые данные намного меньшими является их сжатие (gzip / deflate)).Вы говорите, что большинство данных повторяются - это означает, что они будут иметь высокую степень сжатия.Сжатие может быть включено глобально в конфигурации сервера, т. Е. Вам не нужно менять свой сценарий для этого.

Сжатые «обработанные данные», вероятно, будут несколько меньше, чем «полные данные», хотя ясомневаюсь, что это может быть на 80% меньше.


Теперь о производительности.

Код:

$time = microtime(true);
$data = array();
for ( $n = 0; $n < 25000; ++$n ) {
    $data[] = array('id' => $n, 'text' => 'foo bar', 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
    $data[] = array('id' => $n, 'text' => 'foo bar', 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
    $data[] = array('id' => $n, 'text' => 'foo bar', 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
    $data[] = array('id' => $n, 'text' => 'foo bar', 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
    $data[] = array('id' => $n, 'text' => 'foo bar', 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
}
printf("%.05f\n\n", microtime(true) - $time);

for ( $n = 0; $n < 10; ++$n ) {
    $time = microtime(true);
    $tmp = array();
    foreach ( $data as $row ) {
        $id = $row['id'];
        $tmp[$id]['text'] = $row['text'];
        $tmp[$id]['key1'] = $row['key1'];
        $tmp[$id]['key2'] = $row['key2'];
        $tmp[$id]['key3'] = $row['key3'];
    }
    printf("%.05f\n", microtime(true) - $time);
}
echo "\n";

for ( $n = 0; $n < 10; ++$n ) {
    $time = microtime(true);
    $tmp = array();
    $id = null;
    foreach ( $data as $row ) {
        if ( $row['id'] !== $id ) {
            $id = $row['id'];
            $tmp[$id]['text'] = $row['text'];
            $tmp[$id]['key1'] = $row['key1'];
            $tmp[$id]['key2'] = $row['key2'];
            $tmp[$id]['key3'] = $row['key3'];
        }
    }
    printf("%.05f\n", microtime(true) - $time);
}
echo "\n";

for ( $n = 0; $n < 10; ++$n ) {
    $time = microtime(true);
    $tmp = array();
    foreach ( $data as $row ) {
        if ( !isset($tmp[$row['id']]) ) {
            $id = $row['id'];
            $tmp[$id]['text'] = $row['text'];
            $tmp[$id]['key1'] = $row['key1'];
            $tmp[$id]['key2'] = $row['key2'];
            $tmp[$id]['key3'] = $row['key3'];
        }
    }
    printf("%.05f\n", microtime(true) - $time);
}
echo "\n";

Результаты:

0.26685; 0.32710; 0.30996; 0.31132; 0.31148; 0.31072; 0.31036; 0.31082; 0.30957; 0.30952; 
0.21155; 0.21114; 0.21132; 0.21119; 0.21042; 0.21128; 0.21176; 0.21075; 0.21139; 0.21703; 
0.21596; 0.21576; 0.21728; 0.21720; 0.21610; 0.21586; 0.21635; 0.22057; 0.21635; 0.21888; 

Яне знаю почему, но первый тайминг первого теста постоянно меньше, чем другие тайминги для того же теста (0,26-0,27 против 0,31-0,32).Кроме этого, мне кажется, стоит проверить, существует ли уже строка.

0 голосов
/ 25 февраля 2011

Я считаю, что условные выражения медленнее на любом языке. Это связано с тем, как компилятор и процессор взаимодействуют с кодом. Процессор просматривает код операции, сгенерированный компилятором, и пытается предварительно извлечь будущие инструкции в кэш. Если вы выполняете ветвление, возможно, он не сможет кэшировать следующую инструкцию. Я думаю, что есть какое-то правило, что блок кода, который наиболее вероятно должен быть в части if, и случай, который встречается реже в блоке "else".

Я сделал быстрый поиск в Google, и некоторое время назад в StackOverflow был другой связанный вопрос / ответ: Влияние прогноза ветвления на производительность?

...