Да, в 3.4.0 теперь есть оптимизация, работающая в зависимости от использования $result - если $result используется, то весь остальной вывод метода игнорируется (а значит экономится процессор и память).
Что будет работать некорректно: когда при одном вызове $result используется, а при другом нет. Типа
Главное чтобы во всех ветках/случаях было присвоение. Например чтобы снаружи этого не стоял еще один ^if. :) Простой способ не думать об этом - $result[] в начале.
1. Такое поведение актуально только при объявлении result'а в качестве локальной переменной или при наличии хотя бы одного $result в методе?
Касательно новой оптимизации в парсере: 2. Имеет ли смысл объявлять локальный result в каждом методе при условии, что все медоты возвращают данные только через $result (привычка такая)? Интересуют скорость и расход памяти.
2.1 Влият ли объявление locals в методе или целом классе на объявление локального result'а, т.е. не заменяет ли locals собой result?
2. Имеет ли смысл объявлять локальный result в каждом методе при условии, что все медоты возвращают данные только через $result (привычка такая)? Интересуют скорость и расход памяти.
Да, конечно имеет - на этапе компиляции будет выкинут лишний whitespace.
2.1 Влият ли объявление locals в методе или целом классе на объявление локального result'а, т.е. не заменяет ли locals собой result? locals - по-моему это совсем про другое.
Описанная мной оптимизация - работает во время выполнения. Грубо говоря, после первого запуска метода смотрится факт использования $result и этот факт запоминается. Выигрыш понятно единицы процентов, хотя можно придумать ситуацию, когда разница будет существенной. На тестовой странице Imprimatur I - расход памяти 8876кб - c оптимизацией, 9216кб - без нее.
версия 3.4 сейчас в активной разработке? :) И еще вероятно с пару недель будет в таком состоянии?
Так что пока 3.4 - для тех, кто хочет помочь разработчикам. Удивляться наличию ошибок в ней не стоит, а следует делать _bug.html. Примем с благодарностью, ошибка будет исправлена, код добавлен в копилку тестов. :)
Ну как, locals делает все переменные локальными, получается, что и $result становится локальным (явно объявленным). Но понятно, что сам $result и объявленный result -- системные переменные, которые обрабатываются отдельно. Это я в качестве бреда подумал такое о locals:-)
locals - на самом деле меняет механизм поиска переменных (упрощает процедуру).
Что же касается декларирования, $result - автоматически заводится всегда. А его явная декларация - лишь указание компилятору включить режим оптимизации.
когда речь идёт о head, собщайте дату/время получения вами исходников из cvs
в настоящее время там всё меняется почти каждый день и не все изменения всегда рабочие (и хотя обычно мы не коммитим то, что не проходит тесты, тесты не покрывают всего многообразия конструкций языка и соотв. иногда head версия может вести себя неадекватно в реальных условиях).
т.к. это runtime-оптимизация. для того, чтобы на этапе выполнения понять, есть ли в методе result или нет, надо выполнить все возможные ветки (а для этого, в общем случае, могут подребоваться иные данные).
определение наличия явного присвоения result-у во время компиляции также полностью не решает проблему, т.к. кодер запросто может написать так:
$name[result]
$$name[значение]
название переменной может придти извне, или кто-то может записать в result метода ($caller.result[...]).
и без выполнения всех веток однозначно определить наличие в методе записи в result невозможно (соотв. и ругнуться невозможно).
однако выигрыш от подобной оптимизации оказался существенным, поэтому мы решили пойти на некоторую ломку обратной совместимости, особенно учитывая тот факт, что с нашей точки зрения писать код, который иногда возвращает содержимое result, а иногда содержимое тела -- плохой стиль :)
Если наличие $result определяется динамически после первой компиляции, то почему бы не сравнивать при следующих выполнениях факт обнаружения $result и результат, состоящий только из пробелов и табуляций (ситуация, описанная в начале топика), и при успешном сравнении создавать что-то вроде $debug_explicit_result_found[имя_оператора]?
основная идея как раз в том, что если было обнаружено использование result, то при следующем вызове не накапливать эти пробелы, табуляции и прочий output, а просто игнорировать его, как ненужный.
Проблема в том, что exception ухудшит совместимость. Сейчас в этом случае возвращается пустое значение, что сработает для всех случаев, когда $result просто забыли присвоить значение. Типа
^if($a){$result[<$a>]}
Случаи же когда умышленно делается
^if($a){$result[<$a>]}{<default>}
- скорее исключение, поэтому и выбран вариант без exception.
проблема в том, что для того, чтобы получить выигрыш в этом случае, надо открыть код и исправить кучу мест. понятно, что делать это никто не будет, т.е. оптимизации фактически нет :(
И все, кого интересует расход памяти - исправят, уверен. А кого не интересует - тому в принципе всё равно, будет оптимизация или нет. Неужели невидимая ошибка считается меньшим злом?