За последние 24 часа нас посетили 37957 программистов и 1811 роботов. Сейчас ищут 825 программистов ...

Возвращения массива из функции

Тема в разделе "PHP для новичков", создана пользователем guest2013, 14 апр 2008.

  1. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Господа отцы!
    Пытаюсь разобраться в оптимизации кода. В частности - оптимизация скорости возвращаемых из функций массивов.

    PHP:
    1. <?
    2. function test1($A){  return $A; }
    3. function &test2($A){ return $A; }
    4.  
    5. // $A - массив с очень большим количеством элементов, но для теста возьмем простой массив
    6. $A=Array('первый элемент','второй элемент');
    7.  
    8. $A1=test1(&$A);
    9. $A2=test2(&$A);
    10.  
    11. // Проверим то, что $A,$A1,$A2 ссылаются на разные массивы
    12. $A[0]='A';
    13. $A1[0]='A1';
    14. $A2[0]='A2';
    15.  
    16. /*
    17. Если вывести массивы получим:
    18.  
    19. A: Array
    20. (
    21. [0] => A
    22. [1] => второй элемент
    23. )
    24.  
    25. A1: Array
    26. (
    27. [0] => A1
    28. [1] => второй элемент
    29. )
    30.  
    31. A2: Array
    32. (
    33. [0] => A2
    34. [1] => второй элемент
    35. )
    36. */
    37.  
    Как вы считаете, какая функция работает быстрее?
    Мне кажется что test2.
     
  2. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
  3. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    topas, я имел ввиду с пояснением ответа.
     
  4. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    в данном случае намного важнее сохранность данных.
    и Функции код снаружи будут еще многократно меняться. Или как минимум быть готовы к значительным изменениям без напрягов.
    Поэтому ссылками в пхп увлекаться не стоит совсем. Выгода в скорости ищется в других местах. Это интерпретатор, а не ассемблер и не С++ низкого уровня.
     
  5. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    guest2013
    test1: В силу специфики PHP. PHP работает быстрее с копиями параметров передаваемых в функции значительно быстрее чем с ссылками на переменную. При создании ссылки на переменную PHP выделяет память под эту ссылку, при копировании напротив, используется ленивая загрузка. Т.е. если мы в функцию передадим массив с 10000 элементов, то по сути при копировании никаких действий происходить не будет. Массив будет действительно скопирован, если мы начнем изменять этот массив внутри функции. Тоже самое относится и к разделу "Возвращение по ссылке", только не забывайте:
    Поясню: $a = & test2($somevar);
     
  6. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    topas, пока я писал данное сообщение, появились предыдущие. Я их прочел. Я рассуждал неверно (не знал о "ленивом" копировании). Мои рассуждения были такие (они неверные, кто не хочет может не читать):


    Обратите внимание, на то что аргумент функции передаётся как ссылка. Тогда если записать так:
    PHP:
    1. <?
    2.  function test1($A){  return $A; }
    3.  function &test2($A){ return $A; }
    4.  
    5.  // $A - массив с очень большим количеством элементов, но для теста возьмем простой массив
    6.  $A=Array('первый элемент','второй элемент');
    7.  
    8.  $A1=&test1(&$A);
    9.  $A2=&test2(&$A);
    10.  
    11.  // Проверим то, что $A,$A1,$A2 ссылаются на разные массивы
    12.  $A[0]='A';
    13.  $A1[0]='A1';
    14.  $A2[0]='A2';
    15.  
    16.  /*
    17.  Если вывести массивы получим:
    18.  
    19.  A: Array
    20.  (
    21.  [0] => A2 //--------------------------------- АЙ-АЙ-АЙ
    22.  [1] => второй элемент
    23.  )
    24.  
    25.  A1: Array
    26.  (
    27.  [0] => A1
    28.  [1] => второй элемент
    29.  )
    30.  
    31.  A2: Array
    32.  (
    33.  [0] => A2
    34.  [1] => второй элемент
    35.  )
    36.  */
    Т.е. после операции $A2=&test2(&$A); $A и $A2 ссылаются на один и тот же массив.

    Абстрактно я себе представляю процесс так:
    PHP:
    1. <?
    2. $A1=&test1(&$A); // 1). $ReturnValue=$A; 2). $A1=&$ReturnValue;
    3. $A2=&test2(&$A); // 1). $ReturnValue=&$A; 2). $A2=&$ReturnValue;
    4. // аналогично:
    5. $A1=test1(&$A); // 1). $ReturnValue=$A; 2). $A1=$ReturnValue;
    6. $A2=test2(&$A); // 1). $ReturnValue=&$A; 2). $A2=$ReturnValue;
    7.  
    Как видно, пятая строка использует двойное копирование массива, а шестая - только одно
     
  7. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    topas, не мог ли ты дать ссылочку на этот момент в спецификации (как говориться - носом ткнуть).
    Заранее спасибо.
     
  8. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    guest2013
    Советую отыскать в теме "Советуем литературу" книгу Шлосснейгла
    Вопросы по оптимизации кода рассматриваются более чем достаточно
     
  9. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Нашел книгу (точнее только её обложку):
    Где бы теперь саму книгу найти... (риторический вопрос)

    А что... просто в документации к PHP (та, которая на этом сайте) нет ничего про это?
     
  10. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    есть, надо искать, но опять таки, там не так полно раскрыт этот вопрос.
    Шлосснейгл основательно подошел к вопросу, не просто сказал как правильно, но еще и объяснил почему так происходит

    Ссылка на саму книгу кажется проскакивала на форуме.
     
  11. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Ух... Скачал... ЁПРСТ... Книга в формате djvu - одни картинки (поиск не работает)... Страниц 613... Хорошо хоть ещё, что на русском. Первый проссмотр по оглавлению не дал результатов. 613/50=12 дней уйдет на прочтение данной книги.

    P.S. Как вам такая формулировка из документации PHP.chm:
    .
    ИМХО: сианистов эта фраза может ввести в тупик. :D
     
  12. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    сианистов, не понимающих этой фразы, надо добивать сразу.
     
  13. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Как будет по английски ссылка и как - указатель?
     
  14. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Перевод:
    ссылка - reference
    указатель - reference
    reference - ссылка (значение, уникально идентифицирующее объект или переменную во время выполнения; особый вид указателя в C++)

    Так, что я не понимаю, за что добивать сианистов...
     
  15. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
  16. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    в том и проблема....
     
  17. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Чем отличается скомпилированный код
    int ReturnMe(int *Value){ return *Value; }
    от
    int ReturnMe(int &Value){ return Value; }


    Ничем. Отличие только в семантике. А суть - одна и та же.

    Код (Text):
    1.  
    2. mov eax,[eax]
    3. ret
     
  18. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Пардон за оффтоп.
     
  19. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    Садитесь, два.
    Что не понимаешь - не беда. Что уверен в своем незнании и несешь его пропагандировать - это ужас.
    В гуголь заглянуть не пытался.
     
  20. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Ну.. прочел я В чем проблема?.
    И ещё раз убедился, что отличие только в семантике (тобищ в способе записи).
    Код то генерируется один и тот же... Если не так, то, пожайлуста, приведи контр пример.

    UPD. Приведи, пожайлуста пример с использованием ссылок, который невозможно записать при помощи указателей.
     
  21. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
  22. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Семантика ссылок: (пример с http://window.edu.ru/window_catalog/pdf ... 2&p_page=4)
    Семантика указателей:
    Код (Text):
    1.  
    2.         #include <iostream.h>
    3.         void main()
    4.         {
    5.         int I=123;
    6.         int *si=&I;
    7.         cout<<”\ni=”<<I<<” si=”<<(*si);
    8.         I=456;
    9.         cout<<”\ni=”<<I<<” si=”<<(*si);
    10.         I=0; cout<<”\ni=”<<I<<” si=”<<(*si);
    11.         }
    12. Выведется
    13. I=123 si=123
    14. I=456 si=456
    15. I=0 si=0
    Если откомпилировать два варианта то экзешники получаются одинаковы.

    Повторяю - отличие только в способе записи.
     
  23. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Что-то вы отвлеклись немного
     
  24. guest2013

    guest2013 Активный пользователь

    С нами с:
    19 ноя 2007
    Сообщения:
    109
    Симпатии:
    0
    Штудирую книгу... Пока, к сожалению, не могу найти про "ленивые" загрузки массивов. Читаю далее.
     
  25. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    мда, двойки будет многовато..
    попробуйте описать понятие "операции над ссылками"