Какова производительность PHP strtotime()?

Я делаю несколько больших итераций списка временных меток: помещаю их в таблицы с диапазонами дат и их группировка по диапазонам. Для этого я нашел strtotime() очень полезную функцию, но меня беспокоит ее производительность.

Например, функция, которая перебирает список недель (скажем, с 49-й по 05-ю неделю) и должна определить начало недели и отметку времени в конце этой недели. Полезным способом сделать это будет:

foreach ($this->weeks($first, $amount) as $starts_at) {
  $ends_at = strtotime('+1 week', $starts_at);
  $groups[$week_key] = $this->slice($timestamps, $starts_at, $ends_at);
}

//$this->weeks returns a list of timestamps at which each week starts.
//$this->slice is a simple helper that returns only the timestamps within a range, from a list of timestamps. 

Вместо strtotime() я потенциально мог бы узнать количество секунд между началом и концом недели, в 99% случаев это было бы 24 * 60 * 60 * 7. Но в тех редких случаях, когда есть переключатель DST, 24 должно быть либо 23, либо 25. Код для сортировки, вероятно, будет намного медленнее, чем strtotime(), не так ли?

Я использую те же шаблоны для диапазонов лет, месяцев (месяцев, что очень непоследовательно!), дней и часов. Я подозреваю, что только с часами просто добавить 3600 к метке времени быстрее.

Любые другие ошибки? Существуют ли способы (которые не зависят от PHP5.3!), которые предлагают лучшие маршруты для согласованных, летних и безопасных диапазонов дат?


person berkes    schedule 11.10.2010    source источник
comment
Почему вы беспокоитесь о его производительности? У вас есть доказательства того, что это замедляет работу вашей системы? Если нет, не пытайтесь чрезмерно усложнять решение по ненужным причинам. Помните, что premature optimization is the root of all evil. Пишите читаемый код, который имеет смысл, и оптимизируйте только в том случае, если вы ЗНАЕТЕ, что это будет проблемой...-   -  person ircmaxell    schedule 11.10.2010
comment
Спасибо, что вернули это золотое правило. Тем не менее, strtotime() — очень умная и чрезвычайно мощная функция, она имеет дело со всеми видами пограничных случаев, выполняет обработку естественного языка и так далее. Просто кажется, что он может быть очень тяжелым и медленным.   -  person berkes    schedule 11.10.2010
comment
@ircmaxell: не могли бы вы опубликовать последний комментарий (включая часть о скомпилированном коде C) в качестве ответа? Для меня это и некоторые исследования помогли принять решение по этому вопросу. Я хотел бы принять это как ответ. Спасибо.   -  person berkes    schedule 12.10.2010


Ответы (4)


Почему вы беспокоитесь о его производительности? У вас есть доказательства того, что это замедляет работу вашей системы? Если нет, не пытайтесь чрезмерно усложнять решение по ненужным причинам. Помните, что premature optimization is the root of all evil. Пишите читаемый код, который имеет смысл, и оптимизируйте только в том случае, если ЗНАЕТЕ, что это будет проблемой...

Но еще кое-что, что следует учитывать, это то, что это также скомпилированный код C, поэтому он должен быть достаточно эффективным для того, что он делает. Вы МОЖЕТЕ создать подмножество кода на PHP и сделать его быстрее, но это будет сложная работа (из-за всех накладных расходов, связанных с PHP-кодом).

Как я уже говорил, используйте его, пока не докажете, что это проблема, а затем исправьте эту проблему. Не забывайте, что переписать его для ваших нужд тоже не бесплатно. Это требует времени и вводит ошибки. Стоит ли оно того, если выигрыш минимален (это означает, что с самого начала не было проблем с производительностью). Так что не утруждайте себя микрооптимизацией, если только вы не ЗНАЕТЕ, что это проблема...

person ircmaxell    schedule 12.10.2010

Я знаю, что это, вероятно, не тот ответ, который вы ищете, но лучше всего профилировать его с учетом реального варианта использования.

Мое чутье подсказывает, что, как вы думаете, strtotime будет медленнее. Но даже если он, скажем, в 3 раза медленнее, это имеет смысл только в контексте. Возможно, ваша подпрограмма с реальными данными занимает 60 мс с использованием strtotime, поэтому в большинстве случаев вы просто сэкономите 40 мс (я полностью выдумал эти цифры, но вы поняли идею). Таким образом, вы можете обнаружить, что оптимизация на самом деле не окупится (учитывая, что вы открываете свой код для большего количества потенциальных ошибок, и вам придется потратить больше времени, чтобы исправить это).

Кстати, если у вас есть хорошие инструменты для профилирования, это прекрасно, но даже если вы не сравниваете метки времени, это должно дать вам приблизительное представление.

person Juan Pablo Califano    schedule 11.10.2010
comment
У меня есть kcachegrind и xdebug, выводящие гринды. Я просто надеялся избежать создания целой песочницы для профилирования, спросив, делал ли кто-нибудь это уже и знает, что это либо очень медленно, либо очень быстро. a good programmer is a lazy programmer. Я очень стараюсь быть хорошим программистом :) - person berkes; 11.10.2010
comment
@беркес. Да, я знаю, и разумно спросить, может быть, кто-то знает это. Но в любом случае я бы настаивал на важности рассмотрения любой из этих цифр в контексте вашего реального приложения. И ты единственный, кто это знает ;). - person Juan Pablo Califano; 11.10.2010
comment
@berkes: это всегда будет зависеть от контекста. Хороший программист не ленивый программист. Хороший программист знает, как эффективно распределить свое время. И беспокоиться об оптимизации рутины, не зная, принесет ли она пользу, — пустая трата времени. Помните, что порядка 95% проблем с производительностью будут связаны с 5% вашего кода. Зафиксируйте 5%, и вы получите максимальную прибыль. Но ключевым моментом является выяснение того, какие 5% требуют профилирования... Не думайте, что из-за того, что одна процедура может быть дорогостоящей, она вызовет у вас проблемы. - person ircmaxell; 11.10.2010

Чтобы ответить на вопрос, наконец:

На основе многих тестов, таких как этот: https://en.code-bude.net/2013/12/19/benchmark-strtotime-vs-datetime-vs-gettimestamp-in-php/

Мы видим, что strtotime() более эффективен, чем мы можем себе представить. Так что да, для преобразования строки в метку времени функция strtotime имеет довольно хорошую производительность.

person Matpo    schedule 17.11.2017

Очень интересный вопрос. Я бы сказал, что единственный способ понять это — настроить собственный тест производительности. Обратите внимание на значение microtime() в начале и в конце скрипта, чтобы определить производительность. Пропустите смехотворное количество значений через цикл с помощью одного метода, затем другого метода. Сравните времена.

person Ricky    schedule 11.10.2010
comment
Я согласен с вами, за исключением части «Пропустить нелепое количество значений через цикл». Вы должны использовать разумное количество значений в соответствии с требованиями и ожиданиями вашего приложения. Весь смысл в том, чтобы знать, серьезно ли повлияет использование одного метода на производительность вашего приложения, не зная, какой из них быстрее в абсолютном выражении. - person Juan Pablo Califano; 11.10.2010
comment
Причина, по которой я указал, что нужно тестировать смехотворное количество значений, заключается в том, что вам нужно найти две крайности. Одна крайность — сценарий с одним вызовом strtotime, а другая крайность — сценарий с десятью тысячами вызовов strtotime. Использование разумного количества, скажем, 10 вызовов strtotime может привести или не привести к каким-либо релевантным данным о производительности. Если обнаружится, что выполнение 10 000 вызовов дает время сценария 1 секунду, можно предположить, что один вызов занимает менее 1/100 мс. С 10 вызовами вы не получите эти данные, если только strtotime не займет более 1 мс. - person Ricky; 23.07.2014