Господа отцы! Пытаюсь разобраться в оптимизации кода. В частности - оптимизация скорости возвращаемых из функций массивов. PHP: <? function test1($A){ return $A; } function &test2($A){ return $A; } // $A - массив с очень большим количеством элементов, но для теста возьмем простой массив $A=Array('первый элемент','второй элемент'); $A1=test1(&$A); $A2=test2(&$A); // Проверим то, что $A,$A1,$A2 ссылаются на разные массивы $A[0]='A'; $A1[0]='A1'; $A2[0]='A2'; /* Если вывести массивы получим: A: Array ( [0] => A [1] => второй элемент ) A1: Array ( [0] => A1 [1] => второй элемент ) A2: Array ( [0] => A2 [1] => второй элемент ) */ Как вы считаете, какая функция работает быстрее? Мне кажется что test2.
в данном случае намного важнее сохранность данных. и Функции код снаружи будут еще многократно меняться. Или как минимум быть готовы к значительным изменениям без напрягов. Поэтому ссылками в пхп увлекаться не стоит совсем. Выгода в скорости ищется в других местах. Это интерпретатор, а не ассемблер и не С++ низкого уровня.
guest2013 test1: В силу специфики PHP. PHP работает быстрее с копиями параметров передаваемых в функции значительно быстрее чем с ссылками на переменную. При создании ссылки на переменную PHP выделяет память под эту ссылку, при копировании напротив, используется ленивая загрузка. Т.е. если мы в функцию передадим массив с 10000 элементов, то по сути при копировании никаких действий происходить не будет. Массив будет действительно скопирован, если мы начнем изменять этот массив внутри функции. Тоже самое относится и к разделу "Возвращение по ссылке", только не забывайте: Поясню: $a = & test2($somevar);
topas, пока я писал данное сообщение, появились предыдущие. Я их прочел. Я рассуждал неверно (не знал о "ленивом" копировании). Мои рассуждения были такие (они неверные, кто не хочет может не читать): Обратите внимание, на то что аргумент функции передаётся как ссылка. Тогда если записать так: PHP: <? function test1($A){ return $A; } function &test2($A){ return $A; } // $A - массив с очень большим количеством элементов, но для теста возьмем простой массив $A=Array('первый элемент','второй элемент'); $A1=&test1(&$A); $A2=&test2(&$A); // Проверим то, что $A,$A1,$A2 ссылаются на разные массивы $A[0]='A'; $A1[0]='A1'; $A2[0]='A2'; /* Если вывести массивы получим: A: Array ( [0] => A2 //--------------------------------- АЙ-АЙ-АЙ [1] => второй элемент ) A1: Array ( [0] => A1 [1] => второй элемент ) A2: Array ( [0] => A2 [1] => второй элемент ) */ Т.е. после операции $A2=&test2(&$A); $A и $A2 ссылаются на один и тот же массив. Абстрактно я себе представляю процесс так: PHP: <? $A1=&test1(&$A); // 1). $ReturnValue=$A; 2). $A1=&$ReturnValue; $A2=&test2(&$A); // 1). $ReturnValue=&$A; 2). $A2=&$ReturnValue; // аналогично: $A1=test1(&$A); // 1). $ReturnValue=$A; 2). $A1=$ReturnValue; $A2=test2(&$A); // 1). $ReturnValue=&$A; 2). $A2=$ReturnValue; Как видно, пятая строка использует двойное копирование массива, а шестая - только одно
topas, не мог ли ты дать ссылочку на этот момент в спецификации (как говориться - носом ткнуть). Заранее спасибо.
guest2013 Советую отыскать в теме "Советуем литературу" книгу Шлосснейгла Вопросы по оптимизации кода рассматриваются более чем достаточно
Нашел книгу (точнее только её обложку): Где бы теперь саму книгу найти... (риторический вопрос) А что... просто в документации к PHP (та, которая на этом сайте) нет ничего про это?
есть, надо искать, но опять таки, там не так полно раскрыт этот вопрос. Шлосснейгл основательно подошел к вопросу, не просто сказал как правильно, но еще и объяснил почему так происходит Ссылка на саму книгу кажется проскакивала на форуме.
Ух... Скачал... ЁПРСТ... Книга в формате djvu - одни картинки (поиск не работает)... Страниц 613... Хорошо хоть ещё, что на русском. Первый проссмотр по оглавлению не дал результатов. 613/50=12 дней уйдет на прочтение данной книги. P.S. Как вам такая формулировка из документации PHP.chm: . ИМХО: сианистов эта фраза может ввести в тупик.
Перевод: ссылка - reference указатель - reference reference - ссылка (значение, уникально идентифицирующее объект или переменную во время выполнения; особый вид указателя в C++) Так, что я не понимаю, за что добивать сианистов...
Чем отличается скомпилированный код int ReturnMe(int *Value){ return *Value; } от int ReturnMe(int &Value){ return Value; } Ничем. Отличие только в семантике. А суть - одна и та же. Код (Text): mov eax,[eax] ret
Садитесь, два. Что не понимаешь - не беда. Что уверен в своем незнании и несешь его пропагандировать - это ужас. В гуголь заглянуть не пытался.
Ну.. прочел я В чем проблема?. И ещё раз убедился, что отличие только в семантике (тобищ в способе записи). Код то генерируется один и тот же... Если не так, то, пожайлуста, приведи контр пример. UPD. Приведи, пожайлуста пример с использованием ссылок, который невозможно записать при помощи указателей.
Семантика ссылок: (пример с http://window.edu.ru/window_catalog/pdf ... 2&p_page=4) Семантика указателей: Код (Text): #include <iostream.h> void main() { int I=123; int *si=&I; cout<<”\ni=”<<I<<” si=”<<(*si); I=456; cout<<”\ni=”<<I<<” si=”<<(*si); I=0; cout<<”\ni=”<<I<<” si=”<<(*si); } Выведется I=123 si=123 I=456 si=456 I=0 si=0 Если откомпилировать два варианта то экзешники получаются одинаковы. Повторяю - отличие только в способе записи.