Pull to refresh

Comments 129

Хорошо, что Вы написали последнюю фразу, ждал её с самого начала прочтения. Без неё было бы очень много несогласных.
Я хотел написать ее в начале, но подумал что это будет слишком преждевременно. И многие после неё отмахнуться рукой, мол у меня все ОК, и не будут читать :)
Ммм… а разве в мане не написано, что стандартные типы изначально в ZE2 передаются по ссылке и ZE2 сам будет рулить? Читал об этом года 2 назад =)
Но обычно все-так вот:
<?php
function prepareArr(&$arr) {
print count($arr) * 2;
}


— мало кто делает, обычно отправляют ссылку в функцию тогда, когда она там нужна:

<?php
function prepareArr($arr) {
print count($arr) * 2;
}
$a = array(1, 2, 3, 4, 5);
prepareArr(&$a);


хотя на самом деле всегда можно обойтись (и так даже правильнее) без ссылок вообще:

<?php
function prepareArr($arr) {
print count($arr) * 2;
return $arr; // Не будет иметь никаого смысла, т.к. мы $arr не измеяли, но все же для демонстрации
}
$a = array(1, 2, 3, 4, 5);
$a = prepareArr($a);


Производительность насколько я понимаю не должна потеряться. "&" — это больше нужно было в php4, где логика передачи переменных была немного другая, нежели в php5.

Спасибо за статью.
Вообще-то вариант «обычно отправляют ссылку в функцию тогда, когда она там нужна», так сказать, деприкейтед.
В последних версиях пхп правильным считается только вариант, описанный автором (когда & стоит в объявлении функции).
Спасибо, что просветили. Я редко пользуюсь ссылками (как-то получается без них обходиться), поэтому этого просто не знал.
вот второй вариант совсем нехороший, если функция требует передачи по ссылке, надо определять это в функции. Если не ошибаюсь компилятор даже выкидывает предупреждения типа Ноутис на такое.
Предупреждения будет выдавать, если в php.ini включен allow_call_time_pass_reference. По дефолту, он выключен и не рекомендуется для использования в версии 5 и выше.
Ну, да, я лишь указал на то что если вообще такое писать то будет предупреждение, т. к. «фишка» депрекейтед.
Спасибо, было интересно почитать про подробности работы самого механизма, однако конечный итог не должен быть большим секретом для тех, кто знаком с мануалом по PHP
Do not use return-by-reference to increase performance, the engine is smart enough to optimize this on its own. Only return references when you have a valid technical reason to do it!
Есть способ ускорить свой код в 10-20 раз, перейти на perl или python ;-)
Кривые руки и остаточность заблужений при этом никуда не денутся.
Ускорить код можно даже тем что ты пишеш меньше символов
Конечно! Если все переменные именовать как: $a, $b, $c, а функции соот-но a(), b(), c() и т. п. — то это очень положительно скажется на производительности :) а главное как красиво выглядит код!
$a = 1;
$b = 3;
$c = 5;
$d = a(b($a, $b), c($c));

Очень аскетично! Ничего лишнего :P
Имелось ввиду то что в питоне или перле количество символов которое нужно писать меньше, ну а именование это дело переменных это уже на ваше предпочтение %)
В конце-концов, хватит уже холиварить, это моветон. Название блога и темы прочтите.
Если есть что-то по-существу — сами напишите статью, почитаю с удовольствием и расру вам в комментариях.
Я думаю, в процессе сборки вермсии на сервер, можно и преобразовать (а еще лучше — скомпилировать в байткод), почему бы нет, кто его на сервере читать будет и злодеям код стырить будет труднее.
Вы видимо и скорость печати увеличиваете за счет пропуска «ненужных» букв и знаков препинания.
Я про скорость печати и говорил, только меня неправильно поняли и заминусовали (
Мы просто за вами не успеваем :) но теперь-то мы все правильно поняли и обязательно заплюсуем :)
та я согласен что неправильно написал, но на хабре коменты удалять нельзя (((
Ну не совсем, даже если уж очень кривые руки то перловые масивы, на отличие от php являются настоящими масивами (не асоциативными) от чего быстрее в десятки раз, таким образом если вы в коде используете масивы, а я думаю вы из точно используете и не раз, ваш код уже быстрее в этой части, про другие части можно вести отдельные разговоры.
Речь была о том, что изначально нужно решить проблемы в себе, а потом уже думать о смене инструмента.
Ага-ага. Поэтому некоторые особо извращённые умы используют псевдо-хеши. Типа и хеш и производительность крутая. На читаемость кода как всегда кладётся болт. Не говоря уже о передаче данных в функцию в «расплющеном» виде. Это просто песня. В печку вашу «гипер-оптимизацию».
«Гипер оптимизацию»? Что за псевдо хеши? Мы тут о масивах вообще-то
Кто-то только что хвастался относительно того, что «перловые масивы, на отличие от php являются настоящими масивами». Это, по вашему, преимущество. Псевдо-хеш — извращенская помесь массива и хеша в перле. Курите мануал. Или я что-то проспал и их уже убили?

Справедливости ради надо отметить, что немногое из того, что мне действительно нравится в перле — это ссылки. То, что их надо (в большинстве случаев) явно разыменовывать лично мне очень удобно. В языках, где явного отличия между ссылкой и переменной нету иногда приходится поломать голову.
Вы проспали — их уже убили
Pseudo-hashes have been removed from Perl. The 'fields' pragma remains available.
Можете ознакомиться с perlref
в 10-20 раз?
можно ссылки на тесты? или это «общеизвестно», что пхп тормозит, а перл летает?
Не стоит буквально воспринимать, но тесты есть, к примеру (http://stuffivelearned.org/doku.php?id=programming:general:phpvspythonvsperl) по регуляркам выходит ровно в 10 раз быстрее.
Я тоже хотел бы сравнительные тесты увидеть каких-нибудь типовых операций. Может кто-то натыкался?
Совсем недавно на Хабре кто-то проводил тестирование небольшое. Честное слово не помню названия темы, тэгов или чего-то, что помогло бы в поиске… Но статья была — факт.
Эмм… Может, это не совсем то:
dals.habrahabr.ru/blog/26877/

P.S. Для желающих нажать на красную букву «х» в красном квадратике: это «чорный пеар» топика-ссылки.
UFO just landed and posted this here
То статья трехлетней давности ;) Чем она вас так поразила?
А что за три года такого изменилось, статья хорошо написана
php4 это не php5, вот что изменилось за 3 года.
Поражаюсь, человек вообще не в теме, и ещё пытается что-то доказать.
Синтаксис не изменился, методы также, вообще почитайте статью, это вы «не в теме».
Автор местами ошибается:
Заменим все шестнадцатеричные числа в тексте на их десятичные представления.
Perl:
$text=~s/([0-9A-F]+)/hex($1)/ige;
PHP:
$text=preg_replace_callback('/[0-9A-F]+/i',
create_function('$t', 'return hexdec($t[0]);'),
$text);

Но, простите, короче и легче на PHP написать вот так:
preg_replace('/[0-9A-F]+/ie',"hexdec('$0')", $text);
Проверено, работает.
Одно и то же действие, но какая разница.
Главное — побольше драматизма в словах.

И, кстати, статья в результате говорит, что языки со своими преимуществами и недостатками. Она не однозначно за Perl.
Бесполезная статья.

Автор явно любитель холиваров, раз высасывает из пальца недостатки языка («К недостаткам я бы отнёс её необъятность(документации)» — ага, ппц, недостаток).
Я, к примеру, люблю php, но одновременно уважаю perl. Никогда не позволял себе говорить что-то типа «да ну, php круче перла, а питон ваще сосёт», это всё глупости.
Шутка товарищи, чтож вы так обиделись уже
Ну не принимайте же все так близко к серцу, задели самолюбие или что. Я вот понимаю что питон быстрее перла ну и что если мне кто-то то скажет я с ним ругатся не стану, что поделать если оно так и есть.
Даже с моей колокольни (а я вебом занимаюсь лишь постольку, поскольку работаю в веб-компании) мне кажется, что вы недостаточно хорошо разбираетесь в предмете. Кроме того, найдите в нашем девелопмент-блоге статьи про оптимизацию производительности PHP, на котором у нас написан практически весь front-end.
Я же не говорю что его вообще нельзя использовать, но добиться производительности сложнее. Статьи поищу, как-то с первого беглого просмотра не нашел.
Честно говоря, тоже что-то найти не могу, если найду — откомментирую. В крайнем случае, напишу автору статьи :)
UFO just landed and posted this here
я дико извиняюсь, но процессор никуда не приступает, не отделяет и ничего не избегает. Транслятор, компилятор, интерпретатор, но никак не процессор.
Я же не «железку» называл процессором :)
Я вот не любитель придираться (это к комменту ниже), но меня слово процессор тоже не на те ассоциации навело. И после этого немножко заклинило на фразе «Когда процессор приступает к передаче массива» :)
В данном случае, по-моему, более уместно был бы термин интерпретатор.
Для любителей придираться: предпроцессор
Знаете как расшифровывается PHP? ;-)
видимо вы уже свои проекты настолько оптимизировали, что принялись за такие статьи :)
Вопрос: очень ли у вас много данных передаются куда-нить по ссылкам? У меня в проекте — в 3х методах.
Мое ИМХО — стать полезная для теории, но совсем бесполезна для практики.
Это как минимум познавательно. Знания теории никогда не вредили. Не факт, что прочитав эту статью я откажусь от ссылок, хотя я и так их всегда избегал, но однажды мне такая информация непременно пригодится.
Так я и не говорю, что статья плохая. Я сказал, что она для практики с вероятностью в 90% не пригодится. А на счет того, что теория всегда нужна — это естественно.
К сожалению, наши проекты нуждаются в оптимизации и даже не такой глубокой :) Мы работаем над этим, но параллельное ознакомление с информацией никому еще не вредило.

Признаюсь, для меня эта информация тоже стала новой. Я искал информацию по кэшированию заголовков и на одном из сайтов наткнулся на эту информацию. Кажется, это было на phplens.com, а может я и ошибаюсь.

Прочитал, подумал, опытным путём убедился в достоверности информации.
Да, информация и для меня была новой. И я теперь это буду знать.
Просто меня всегда удивляли тесты, которые проводились над 10000-10000000000 элементов данных, притом не задумываясь, а вообще возможно ли использование в реальных проектах такого количества элементов? Просто я практических применений такому количеству использования ссылок не вижу.

А так да. Новые знания не помешают :) Спасибо )
Бывают случаи, когда циклы таких размеров имеют место :) Например, у нас в одном из проектов некоторые данные кэшируются и есть инструмент обновления кэша, который при необходимости мы запускаем «ручками». Там некоторые циклы довольно велики.

Так же большие циклы имеют место для решения и типовых задач, например при обработке файлов в каталогах.
> Надеюсь, никто не ждал, что значение переменных окажется одинаковым? :)
Ещё одна неочевидность в ПХП. Перемненные то разделяются, то обратно соединяются.

Познавательное: в этом плане в сишарпе всё куда строже, и в вышеупомянутом примере значения оказались бы одинаковыми, ибо переменной присвоилась бы ссылка, а копирование нужно затребовать явно.

no offence, сам пхп очень люблю :)
> Использование ссылок оправдано только тогда, когда это имеет смысл с функциональной точки зрения.

А вы до этого просто так передавали, чтоли? Перача по ссылке служит для модификации, а не для «что-бы быстрее работало потому что по ссылке».
>Переменной $b присваивается значение переменной $a, при этом сами данные никуда не копируются! Вместо этого переменная $b преобразуется таким образом, что бы указывать на тоже место в памяти, где хранится переменная $a

Поделитесь пожалуйста ссылкой на источник этой информации.
Написал тут:
habrahabr.ru/blogs/php/43489/#comment_1079708

Если найду оргинал обязательно дополню текст ссылкой. Пока помню только что это была большая статья, одним вопросов которой было рассмотрение передачи значений по ссылке. Примеры там были почти такие же, как я привел.
Процитированное — это как раз то место, после которого можно не читать.
Почему не читать? Copy-on-write появилось в том же перле лет эдак 15 назад, отчего бы и разработчикам пехапе до того же самого не дойти сейчас?
Дерик на phpConf в прошлом году рассказывал об этом. Можете попробовать найти аудио с конференции…
О, спасибо. Кстати, я на торрентс. ру видел подборку видео 2007 года.
У Ильи Альшанетского в его знаменитых советах по производительности где-то это было.
Версия PHP? Был ли использован какой-нибудь кеш или оптимизатор кода?
У меня локально установлен PHP 5.2.4 без каких-либо модулей кэширования.
Знаете, я внимательно прочитал статью. Вы не ту проблему подняли. Передача по ссылке не является злом (для увеличения производительности она не оправдана, но это другой вопрос), вы рассмотрели интересную ситуацию о которой я, например, не задумывался, за это вам спасибо. Но акценты, на мой взгляд, надо было бы расставить иначе. Именно отталкиваясь от приведённого примера.

Надеюсь, никто не ждал, что значение переменных окажется одинаковым? :) Шутка


Ну какая же это шутка? Программист на Python этого будет ожидать.

>>> a=[1,2,3,4,5]
>>> b=a
>>> a.append(6)
>>> print a,b
[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
Ну так в Питоне вообще всё на ссылках. Там и более забавные шутки есть. Типа:

def test(a = []):
a.append('test')
return a

Как думаете, что получится, если функцию вызвать 10 раз? )

На сайте IBM по этому поводу пара хороших статей есть. В принципе старенькие, но многое до сих пор актуально.
Изящество и неловкость Python. Часть 1
Изящество и неловкость Python. Часть 2
Неправильно. В Пайтоне вообще всё на класс-объектах, а они передаются по ссылкам. Это нормально. В PHP тоже все передаётся по ссылкам.

Конечно же я знаю что произойдёт, если вызвать её 10 раз. И я даже знаю, что делать, чтобы этого не было.

Вы ошибаесь, если думаете, что это происходит только из-за того, что объекты в Python передаются по ссылке. Такой эффект, и это немаловажно, возникает ещё и из-за того, что аргументы вычисляются в момент объявления.
Я знаю когда в Питоне вычисляются аргументы. ) Кодга я писал «всё на ссылках» я имелл ввиду «всё что только можно передаётся по ссылке». Пример был просто примером своеобразия.
в php тоже
$a = new Foo();
$a->bar = 1;
$b = $a;
$a->bar = 2;
echo $a->bar, ' ', $b->bar
только это справедливо для объктов.
попробуйте вот это:

$a = new ArrayObject();
$b = $a;

$a[] = 1;
var_dump($b);
Если нужна копия объекта, нужно вместо $b = $a писать $b = clone $a. Иначе копируется ссылка, а не сам объект.
ну так я как раз и намекал на это, в php объекты ведут себя в этом плане так же как в python
Это в PHP5 насколько я помню, там все объекты по-умолчанию передаются ссылкой.
> Использование ссылок оправдано только тогда, когда это имеет смысл с функциональной точки зрения.
А разве есть другие предпосылки к их использованию? о_О
Раз была написана статья, значит многие так думают. Но почему?
UFO just landed and posted this here
к какой версии PHP это применимо?
Как я уже писал выше это актуально даже для PHP 5.2.4
так я где-то натыкался на фразу разработчиков php о том, что нет необходимости в передаче значений по ссылке, так как они уже оптимзировали этот момент
может даже в мануале
Я здесь эту фразу уже цитировал, правда она относится не к ссылкам в целом, а конкретно к возврату значения по ссылке из функции.
я например использую ссылки только когда:

$arr = array(...);
someFunc($arr); // передается ссылка
$arr =… // уже другой…

На мой взгляд такой вариант будет занимать больше памяти:

$arr = array();
$arr = someFunc($arr); // передается Не ссылка!!!
8 яедрные хеоны, супербыстрая память, раиды — а они все наносекунды вычисляют.
Их где-то бесплатно раздают? :)
проектам, которым нужна это микрооптимизация, могут себе позволить нормальные сервера.
Но это же не значит, что стоит делать по принципу «лишь бы работало».
то есть без микрооптимизации и экономии 1 секунды на 10к запросов — это «лишь бы работало»?
10к, 20к, 1к или 0.001к — зависит от объема передаваемых данных. А если все это ещё и в цикле…
Вы все правильно написали.

Но улыбнуло то, что это похоже на сенсацию или великое откровение :)
Неужели людей, которые использовали ссылки для скорости так много? Похоже на то…

Одна из проблем PHP да и любых языков сильно высокого уровня в том, что часто люди пытаются проводить сверхнизкоуровневую, «ассемблерную» оптимизацию. Это приводит к куче проблем и головной боли, но результат как правило мизерный. При этом часто забывают об оптимизации на высоком уровне (БД, кеширование), которая может дать 20-90%

Подобные языки не предназначены для такой оптимизации, для хардкора есть C++, C и ассемблер. Вы либо принимаете язык полностью, таким какой он есть, либо ищете другой. Об этом хорошо написал Бьерн Страуструп.
Как-то странно получается, Бьерн Страуструп он-же вроде и является создателем языка С++, он так и написал: «Подобные языки не предназначены для такой оптимизации, для хардкора я изобрел вам С++»? :P
>> Вы либо принимаете язык полностью, таким какой он есть, либо ищете другой.

Вот об этом он писал.
C++ кстати совсем не для хардкора разрабатывался, а для реализации огромных проектов, но позволяет писать на низком уровне Си (про ассемблер помолчим :)
UFO just landed and posted this here
Да, но по сравнению с PHP Си — машинный код.

>> А в PHP передача аргумента по ссылке работу всё-таки ускоряет.

Сегодня ускоряет, завтра тормозит… Работу ускоряет высокоуровневая оптимизация, например БД и кеширование.
UFO just landed and posted this here
В любом случае это сильно завязано на текущую реализацию движка PHP, которая со временем меняется. В 98% объема кода реального проекта такая оптимизация нафиг не нужна. А если действительно есть потребность максимально ускорить критичные вещи — такой функционал можно вынести в модули PHP. Правда их писать никто не умеет, но это уже совсем другой вопрос.
UFO just landed and posted this here
Но мне интересно, например у вас огромный массив с информацией на 2 мб в памяти (до пустим) и вы чтобы сделаете функцию которая что-то будет вытворять с массивами, а затем возвращает результат, вот при таких ситуациях и нужны ссылки, т. к. еще + 2мб не хочется забивать под результат функции… легче сразу передать ссылку на массив в функции, и пусть она делает с ним все что хочет, без лишних телодвижений…
Да, но это опять же работает только если вам нужно изменить исходный массив этой функцией. Здесь ссылка используется из-за другой логики, а не для ускорения/оптимизации. Другими словами неиспользование ссылки потребует дополнительных ресурсов.
UFO just landed and posted this here
Да, C является языком высокого уровня, технически, но разрабатывался он как раз как замена ассемблеру, afaik.
Да, наверное не предназначены. Но бывают некоторые простые вещи, которые можно сразу учесть при написании кода и лишним это не будет.
UFO just landed and posted this here
Вы наверное не поняли автора. Речь шла об отказе от необоснованного использования ссылок для якобы ускорения работы. То есть статья о том, что «То, о чем все знали что оно нафиг не нужно, действительно оказалось нафиг не нужно». :)
UFO just landed and posted this here
Спасибо за отзыв, пусть и жёсткий :) Мне только кажется, что вы не прочитали последние строки топика или просто не уделили им должного внимания. А в них вся суть: я не пропагандирую отказ от использования ссылок, я пропагандирую отказ от моды их бессмысленного использования. Очень хорошо что Вы и другие понимают где их использование оправдано, а где нет.
UFO just landed and posted this here
UFO just landed and posted this here
Странно, что в статье copy-on-write как только не называли, но никак не этим термином :)
И правда… Спасибо за замечание :)
Лет 5 назад я впервые столкнулся с парсингом XML. Ну и как водится начал изобретать велосипед. Длинный (15mb) XML разбирался и из него строилась древовидная структура. Жесткая рекурсия, все дела. Как водится у начинающего web-программиста который общался с Си ))), подумал что передача параметра по ссылке ускорит дело. Ога! Щаз ))) На форуме xpoint надо мной посмеялись и посоветовали учить матчасть ))) Там же супермега мозги сидят ))) Ссылки наше все!!!

В итоге после экспериментов быди сделаны выводы, что ссылки в РНР есть зло и ахтунг.
Причем в случае с рекурсией, когда в функцию передается большой параметр, лучшая производительность была достигнута с использованием статической переменной.
Я не говорю, что это лучшее решение, просто тогда для меня производительность данной процедуры была критична, а решение вполне приемлемым.

А потом я переучился на Perl и понял где щасье ;)
UFO just landed and posted this here
«кунцкамеру» => «кунсткамеру»
Вас бы в библиотеку, учить матчасть…
Вас бы в библиотеку, преподавать мат. часть :P
Еще пару примеров с одинаковым функционалом, один со ссылками, другой без:

function change(&$arr) {$arr[] = 1;}
$start = microtime(true);
for($q=0; $q<5000; $q++) {change($a);}
echo microtime(true)-$start;

Второй:

function change($arr) {$arr[] = 1; return $arr;}
$start = microtime(true);
for($q=0; $q<5000; $q++) {$a = change($a);}
echo microtime(true)-$start;

Первый исполняется за 0.00684 с., второй — за 1.20769 с., разница в 176 раз. Так что ссылки не есть асолютное зло и не значит что их не нужно применять для оптимизации.
1. Примеры не показательны.

2. $b = $a; делается для того, чтобы сохнарить «старое» значение?
В любом случае либо $a, либо $b будет изменён и будет создана копия массива в памяти. В данном случае мы можем выкрутиться и отложить копирование на потом, но мы всё равно ничего не выигрываем в общем. Или я что-то ещё упускаю?

3. Спасибо за тему. Интересно ))
Ну и по форме статья написана нормально. Надо теперь добить тему по сути ))

Успехов.
Оффтопик, конечно. Просто странно что никто не указал раньше. В первой картинке передаем по ссылке одну переменную, а каунт берем от другой, которая не объявлена (:
Теперь ещё интересно было бы узнать цифры по исполнению foreach со ссылками:

foreach ($array as &$row) {
    $row['a']='b';
}


супротив

foreach ($array as $k=>$row) {
    $array[$k]['a']='b';
}
Only those users with full accounts are able to leave comments. Log in, please.

Articles