Pull to refresh
186
0
Евгений @evgenyl

User

Send message
Ну тут вы не совсем правы. У бота есть вполне себе стратегическое мышление, и даже подобие hive-mind.
Возьмите те же «миссии» для муравьев, логику «не посылать в атаку на муравейник больше 4-х муравьев, или если их меньше 10, то только одного»; расчет того, как двигаться при каком перевесе сил и т.п.
Тут скорее стоит право внести ремарку, что это не стратегическое, а тактическое мышление (это всё же разные вещи), но согласитесь что при столь значительном рандоме (карты, еды, противников и т.п.), гораздо эффективнее сосредотачиваться именно на тактике, нежели длительной стратегии, что собственно данный бот и доказал.

А так конечно можно доводить к идеалу до бесконечности (засады, удары в тыл, фланговые атаки и т.п.), но это уже на мой взгляд отняло бы значительно больше времени, особенно у одного человека.
Такое же как и остальных местах — перечисление параметров.
Просто именно у echo есть особенность поведения:
echo 'hello ', 'world!';
равносильно:
echo('hello ');
echo('world!');

Это кстати одно из ее отличий от print, который не позволяет такую передачу параметров.
Длина переменных в PHP не является как таковой проблемой, потому как еще на стадии OpCoda происходит определенная оптимизация. Это можно видеть по например такому опкоду ( www.heypasteit.com/clip/05DW ):
compiled vars: !0 = $a // тут в !0 используется как идентификатор для переменной с именем $a
// и дальше работа уже непосредственно с этим идентификатором
INIT_ARRAY ~0 // Создаем массив ~0
ASSIGN !0, ~0 // Присваиваем $a созданный массив

Так что имена переменных конечно хранятся, но жертвовать их длиной в ущерб читаемости — это «экономия на спичках».
Во первых, указывайте откуда вы берете цитаты.
В данном случае это цитата отсюда: php.net/manual/en/features.gc.collecting-cycles.php
Это касается описания сборщика мусора для ЦИКЛИЧЕСКИХ ССЫЛОК, который появился в 5.3, а не обычного сборщика мусора PHP, про который я писал вам.

Это два разных сборщика мусора.

Да вашей цитате есть очень важное слово: Only when the root buffer is full does the collection mechanism start for all the different zvals inside.

Сборщик циклических ссылок запускается когда заполняет буфер «корневых ссылок».

Вы начинаете путать одно с другим.
Конечно нет.
Потому что в постер этого «бага» явно не читает документацию по сбору циклических ссылок. Об этом прямо ответила администрация.
Решил всё-таки найти в документации.
Почитайте: de3.php.net/manual/ru/features.gc.refcounting-basics.php
Особенно смотрим вот это:
«Как только „refcount“ станет равным нулю, контейнер уничтожается. „refcount“ уменьшается на единицу при уходе переменной из области видимости (например, в конце функции) или при вызове unset() с данной переменной.
Если мы сейчас вызовем unset($a);, то контейнер, включая тип и значение, будет удален из памяти.»
Ну или мы налицо имеем баг документации PHP.
Если я что-то упустил и что-то не так понимаю — подскажите где почитать.
Прочитайте (еще раз) вот этот комментарий. Измените и еще раз проверьте ваш кейс.
И ответьте на первый вопрос комментария.
Полагаю это разрешит вопрос.

В PHP высвобождается память на основе подсчета ссылок. Если переменная выходит из области видимости, то у нее обнуляется счетчик ссылок и она удаляется. Тоже самое происходит и при unset. Память высвобождается сразу. Так что тут вы не правы. Стандартный сборщик мусора как раз и занимается таким обнулением и очисткой, при выходе из функций, завершении скрипта и т.д. Сборщик циклических ссылок занимается этим только при переваливании числа ссылок за 10000 или же при ручном вызове.
Если бы всё было идеально так как вы говорите, тогда бы налицо был виден баг в отображении информации потребления памяти через memory_get_usage(), и мы бы видели эти утечки, или «задержки обработки сборщика мусора».

То есть, если я правильно понял этот набор цифр, вы предлагаете только ради экономии в 1 секунду на миллион вызовов функции count() везде применять передачу по значению?

Кстати если вы уберете count() из функции, и скажем замените какой-либо операцией вроде $b = strval($a[0]);, то разница исчезнет, так что даже ваша секунда скорее всего просто связана с тем, как count работает со ссылками и значениями, а вовсе не с передачей ссылки или значения в функцию.
Может поясните, каким это образом это опровергает?
В вопросе программирования я как бы привык доверять больше цифрам, нежели умозрительным заключениям. Пока же цифры показывают, что память остается. И это абсолютно логично, так как переменная не уничтожается, а присваивается null значение (остается zval контейнер и запись об имени переменной).

Хотелось бы увидеть что-то конкретное, иначе это уже смахивает на троллинг )
Интересный у вас подход. Сами сделали утверждение и просите других, чтобы вас убедили и предоставили вам доказательства )
Я уже написал вам: «Не уверен что это как-то значительно скажется на быстродействии, если вообще скажется.»

И тем не менее сделаю вам одолжение:
Оборачиваем ваш пример в код для отладки и проверки памяти.
Смотрим xdebug_debug_zval('a'); внутри вызова функции:
в случае с function a1(array &$a) получаем
a: (refcount=3, is_ref=1)=array (… )
в случае с function a2(array $a) получаем
a: (refcount=3, is_ref=0)=array (… )

Единственное изменение, это индикатор ссылки-переменной в одном случае =1, в другом =0, что логично.
В обоих случаях потребление памяти одинаковое, так как никаких действий с массивом в ваших примерах не производится (имеется ввиду изменение значений) следовательно и копирования с выделением памяти не произойдет.
Вы действительно хотите найти существенную разницу в производительности между конкретно двумя этими функциями только из-за передачи значения по ссылке или через оптимизированное копирование?

Давайте даже посмотрим OpCode двух этих функций:
Через копирование: www.heypasteit.com/clip/05DW
Через ссылку: www.heypasteit.com/clip/05DX
Разница между двумя опкодами только: в 7-ой строке SEND_VAR или SEND_REF

Если у вас есть желание, можете копнуть еще глубже (тут уже только в С код) и найти всё же те различия, о которых говорите.
Пожалуйста, внимательно читайте то, что написано в ссылках, которые вы даете. Первый же комментарий от администрации: [2010-10-09 18:02 UTC] johannes@php.net
"… описанная вами ситуация не является багом. Пожалуйста, прочитайте документацию касательно того, как обрабатываются циклические ссылки de3.php.net/manual/en/features.gc.collecting-cycles.php ...".
Нет предела совершенству.
Но если бы всё было так очевидно, не приходилось бы задумываться, спрашивать и узнавать, а в этом есть своя польза ;)
Принимаю ваши доводы, пусть суть и не меняется, но термин выбран не корректно и может запутать тех кто столкнется с этим явлением впервые. Поправил статью. Спасибо за уточнения.
Здесь написана какая-то хрень.
foreach($a as $k => $v) исходный массив копирует полностью при первом изменении (то же самое происходит при любой передаче «по значению» в функцию).

Полного копирования не происходит. Посмотрите внимательнее на примеры в статье. Если под «полностью» мы подразумеваем с вами и структуру массива и его значения. Либо мы с вами друг друга не поняли, и тогда прошу вас привести конкретный пример, чтобы было понятнее. Мне интересны ваши доводы.

В остальном ваши замечания справедливы. Не описал в статье явно эту тонкость работы, а именно различие между копированием структуры и копированием значений, что становится существенно при большом числе элементов, а не объеме значений.

С вашего позволения добавлю ссылку в статью и на ваш комментарий, чтобы информация получилась более целостной.
Для удобства просмотра расхода памяти. Первое присвоение создает переменную и выделяет под нее память, но эта память «до» присвоения, второе же присвоение уже содержит объем памяти с учетом переменной $base_memory_usage.
1. Насчет 2% случаев это очень условно. Если человек пишет только мини-скрипты «на коленке», тогда конечно да. Если же приложения по-серьезнее, то учитывать такие моменты придется уже не в 2% случаев, а например в каждом скрипте, где есть обработка данных из БД.
Я сам был бы рад узнать всё это из книг, но к сожалению мне таковые не встречались пока.

2. Не совсем понимаю каких именно выводов вы ожидали? Сколько ситуаций — столько и выводов. Здесь важен именно механизм, а применять ли его и как именно — это уже вопрос конкретной ситуации.

3. Я не стремился впихнуть абсолютно всё в одну статью, да и сама статья называется «Работа с памятью», а не «Как PHP управляет памятью». Согласитесь, что это немного разные вещи. И хотя сборщик мусора и важная вещь, но если не считать редкие случаи использования коллектора циклических ссылок в 5.3, то вы практически никогда не будете использовать его сами напрямую в скрипте.

4. Использование памяти скриптом, а именно аллокация при старте и последующей работе, в очень значительной мере зависит от самой OS, интерпретатора и их настроек. Это уже не только вопрос работы с памятью в скрипте, а гораздо более широкое понятие со множеством уникальных случаев. И данная тема также не является предметом данной статьи.

5. Насчет ухудшения быстродействия хотелось бы увидеть от вас пример или ссылочку. Если я ничего не путаю, то передача по ссылке просто изменяет значения refcount__gc и is_ref__gc в _zval_struct. Не уверен что это как-то значительно скажется на быстродействии, если вообще скажется.

6. Посмотрите в пример внимательнее. Там прекрасно видно когда выделяется новая память, а когда используются ссылки. Если вы считаете что это не говорит о количестве новых zval контейнеров и и переменных, тогда было бы замечательно увидеть от вас пример, что это не соответствует действительности и приводит к потере скорости. Полагаю что многим было бы интересно прочитать про найденный вами баг, поправлю статью при необходимости. Касательно скорости опять же не совсем понимаю где должна произойти ее потеря, если речь идет только об изменении счетчиков ссылок.

В целом же по вашему комментарию можно сказать, что вы знаете что-то, что очень было интересно многим прочитать. Было бы интересно увидеть от вас статью на указанные вами темы.
Ну согласно бихевиоризму, нет никакой разницы.
Тогда скорее не «строиться», а «корректироваться». И это не «будет», а «уже есть».
Не для кого не секрет, что информационная безопасность страны подразумевает
и социальные сети, и поисковую выдачу и многое многое другое.
Ваше утверждение верно только если у каждого по одному муравейнику. Но если это было так, карта была бы совершенно по-другому сгенерирована.
Посмотрите внимательно на карту из примера.
Там у каждого бота по 5 муравейников. Следовательно если будет обнаружен муравейник 113,32 для бота, который владеет муравейником 143,2 тогда он как минимум получает 5 осей для расчетов примерного местоположения других муравейников.

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

Конечно нужно учитывать размерность карты и количество муравейников и каждого бота (это легко посчитать по своим муравейникам). Соответственно и паттерн смещать надо также.

В вашем примере это легко увидеть, что обнаружив указанный вами муравейник, нужно сделать аналогичное смещение для каждого своего муравейника, и тем самым получить еще 4-ре предположительные точки, где есть вражеские муравейники.

Information

Rating
Does not participate
Location
Россия
Registered
Activity