Как стать автором
Обновить

Комментарии 38

Это что, ASSEMBLER экспортируется в PHP? Зачем они это делают? Интерпретатор должен интерпретировать, а не создавать виртуальный стек, который здесь ни к чему.
Ну почему, очередей в PHP раньше не было (встроенных), а теперь хоть какие-то есть :).
Да вобщем-то давно оно уже есть ) Хотя хороший пост хотябы для популизации
Ну, простые-то очереди были через array_push() / array_shift(). Или, соответственно, array_unshift() / array_pop().
Проблема в том, что «очереди» через array_shift() обладают производительностью O(N), потому что массив пересоздается заново.
Простые и с O(N) потянут. А сложные — это уже, скорее, будет не уровень одного PHP-процесса. А межпроцессное взаимодействие, отдельные клиенты и обработчики. И тут уже лучше пойдут более специфичные инструменты, типа реализаций AMQP или Gearman.

То есть безусловно новое решение наверняка полезно, но ответ был на комментарий «теперь хоть какие-то есть».
Классическое «слышал звон — не знаю где он»,
По моему эти никто никогда не пользуется.
Пользуюсь регулярно, так как проект хайлоадный и место узкое. Не говорите глупостей, это полезные вещи.
Наверное правильнее спросить где и когда можно это использовать. Мне допустим это очень интересно. Например как на практике можно решить какую либо проблему с помощью этой библиотеки. Если привести короткий пример из жизни было бы супер.
В следующей части статьи будут рассмотрены итераторы. Там будут примеры из жизни.
Насчет структур данных: тут например можно про «кучу» прочитать и область ее применения, а тут про очереди. На самом деле вещи довольно полезные, да и код теперь будет намного красивее
При реализации forth-машины на php :)

А так, например, стэки широко используются при анализе или обработке вложенных структур данных, в частности при вычислении математических выражений. Очереди при обработке списков «заданий», скажем сначала парсим текстовый ввод в виде какого-то списка на отдельные элементы, нормализуя его в одном цикле, а потом обрабатываем нормализованный список в другом.

Собственно какие-то особенные проблемы эти типы данных не решают, но бывает решаешь задачу и смотришь «о-па, стандартный тип, можно велосипед не изобретать, он уже есть в „ядре“» или даже «блин, писал-писал, а стандартный тип получился, надо нафиг удалять, чтобы не позориться». Типа паттернов, но чисто для данных. Упрощают не сколько написание кода, сколько его понимание другими (или собой через некоторое время :). Естественно при целевом использовании.

Я не смог понять вот эту фразу: "… — это список узлов, связанных в обоих направлениях друг между другом."
Автор, ты не мог бы перефразировать это как-то более по-русски?
Заранее спасибо.
Второй узел указывает как на первый, так и на третий. Третий на второй и четвёртый. В общем для любого элемента списка определен предыдущий узел и последующий без явной нумерации. Кроме граничных, конечно, у первого нет предыдущего, а у последнего нет последующего.
Господи, как можно хоть сколько-нибудь знать о программировании, и не знать, что такое и как устроен двусвязный список?
Новое поколение не читали Кнута и не изучали структуры данных. Про деревья лучше не упоминать ;)
Не учиться в универе например. И быть «крутым самоучкой». =) Это не про всех конечно. Но зачастую тенденция такова =)
Зачем лезть в программирование, даже на PHP, если не знать элементарных вещей типа двусвязных списки? И причем тут ассемблер? И как это никто это не использует? В PHP есть, конечно, очень удобный и гибкий array, но для некоторых задач более оптимальным решением будет использование специфичных структур данных. Не для удобства, а для экономии ресурсов, если кто-то об этом вообще думает.
pop/push стандартные операции по работе со стеком в ассемблере. Хотя есть popw и тому подобное… расширяющее это дело. Конечно, оно мало связанно, иначе, чем названием.

Мне более интересно как это использовать. Вот, скажем, есть список продуктов и список их модификаций, в связанном списке (с ценой, названием и т.п.). Как ускорить сортировку, получая это дело в связанный список, как сделать аналог array_multisort(). Скажем 2000 продуктов. 20 тыщ. цен. А хостинг слабый (rssites, masterhost) — как ускорить этим делом.

Извините, приземлен к своим задачам…

ПС. Лезу (за деньги) 16-й год. Зачем? Чтобы выжить.
Да тогда можно приводить в пример практически любой другой язык, так как почти везде есть очереди, стеки, списки и т.п.

В случае со списком продуктов и сортировкой связные списки ничего не дадут. Они эффективны тогда, когда нам нужен последовательный доступ к данным, то есть когда порядок обхода такой же, как при записи. В случае же, когда нужен случайный доступ к данным, в частности при сортировке, связные списки будут плохо работать. А сортировку в вашем случае лучше осуществлять на уровне запросов к БД, так как вряд ли там она будет выполняться медленней, чем если вы будете это делать в коде.
А я именно для удобства использую :) Вернее для семантики. Если написал, что это стэк, значит это стэк и незачем лезть в его середину или начало, бери элементы только с вершины.
Зачем лезть за руль машины, если не знать элементарной структуры атома железа, как выращивать каучуковые деревья и добывать каучук?
Зачем заниматься сексом, если не знать что выделяет элементарные гормоны и как они влияют на организм?
Примеров на данную тему в общем то масса.
На самом деле нет.
Включите, пожалуйста, в статью код тестов SplStack. Странно, что специализированная структура данных не дает преимущества в скорости перед стандартным массивом. Вы ведь его имели в виду, говоря об использовании функций array_pop и array_push?

Еще хорошо бы протестировать и сравнить потребление памяти array и специализированными структурами — это зачастую даже важнее прироста производительности.
Вот да. Из статьи получается, что специализированные структуры дают лишь минимальный прирост скорости, а то и вообще никакого не дают — не очень понятно тогда, есть ли смысл вообще с ними заморачиваться.
Тесты какие-то очень синтетические. Скажем самый простой случай стандартного типа FixedArray меряет скорость заполнения массива, но никак не меряет скорость доступа к нему. А на практике как-то заполнение операция одноразовая, а вот доступ постоянная.
На днях постараюсь провести новые тесты и разместить их результаты в этой или новой статье.
Я вот наверное злой какойто. Но блин, эта штука есть в php уже давно и поэтому меня немного поражают неокторые комментарии к статье. Статья то хорошая. Но какой блин нахрен ассемблер, причем он тут вообще? Причем тут списки продуктов? Ну то есть понятно, что оно так или иначе приведет либо к прикладной задаче, либо будет прослеживаться ряд аналогий. Но это же библиотека, которая позволяет использовать классические структуры данных в своих задачах и делать это удобно.
Насчет использования — очереди собственно для очередей чего угодно: сообщения, задачи… ну многие другие ситуации часто являются подмножествами. FixedArray — очевидно для того, чтобы знать о размере занимаемой памяти. Хранилище объектов удобная штука когда нужно хранить набор объектов определенного типа + оно реализует ряд интерфейсов типа итератор, array access и других, что тоже полезно.
Это же хорошие и удобные штуки, да еще и в ООП стиле.
Хотелось бы спросить, чем статья лучше мануала?

Статья оформлена по принципу
— берём раздел мануала
— смотрим в википедии незнакомые слова или слова которые автор думает будут незнакомы среднему хабраюзеру, копипастим описание
— если в мануале есть описание, берём его тоже
— добавляем слова «РАССМОТРИМ ПРИМЕР» или «НАПРИМЕР»
— копипастим пример из мануала
— добавляем слова «На этом мы закончили изучать структуры данных SPL.»

Мне кажется, было бы гораздо больше пользы, если бы автор внёс всё это в русскую документацию по php, а здесь просто отставил ссылку. И ему карма и рейтинг, и польза какая-никакая.
я ен сравнивал статью с маном, но в целом статья не плохая.
было бы не плохо, если автор действительно прислушиется Вашего совета и внесет свой вклад в развитие рускоязычного мана.
Цель статьи — популяризовать такие вещи, как эта библиотека. Чтобы новички увидели какие есть штуки и использовали их. После написания последней части я постараюсь перенести это в русскую документацию.
Я конечно злой, но… ни продолжения цикла, ни уточненных тестов которые обещали, ни собственно русской документации)
Наверное, основное отличии структур-списков от массивов с позиции использования — передеча их аргументом в функции. Очевидно, что массив передается по значению, а список (например, SplFixedArray) — по ссылке. Из-за этого они как минимум не взаимозаменяемы логически. И в зависимости от потребностей одна из двух структур (массив против списка) может быть удобнее.
Ничто не мешает нам передать в функцию массив по ссылке при помощи &.

Даже если согласно сигнатуре функции массив должен быть передан по значению, на самом деле он передается по ссылке и только при попытке внести в него изменения будет на лету скопирован (copy on write). Поэтому не вижу, чем использование SplFixedArray будет оптимальнее.
В SplStack
echo $stack->serialize();
не выполнится, если версия PHP 5 < 5.4.0. И что интересно, там был баг с неправильной сериализацией, который закрыли в день написания этого топика :)

Кучи являются древовидными структурами: каждый узел больше или равен своим потомкам, при этом для сравнения используется внедренный метод сравнения, который является общим для всей кучи. SplHeap реализует основную функциональность кучи и является абстрактным классом.

Ну так продемонстрируйте пожалуйста, как в узел SplMinHeap или SplMaxHeap можно сохранить несколько потомков. К сожалению, на самом деле это никакая не куча, а всего лишь связный список с сортировкой при вставке/удалении.

Кстати проверил:

1) обход через итератор идентичен извлечению через extract, т.е. от кучи ничего не остаётся

2) пересортировка при удалении реально есть. То есть создали кучу из объектов, один объект изменили при переборе он окажется на нужном месте:

<?php
$heap = new SplMaxHeap();
foreach ([16, 7, 11, 8] as $val){
    $item = (object)['foo' => $val];
    $heap->insert($item);
}
$obj = (object)['foo' => 6];
$heap->insert($obj);
foreach ([10, 15, 5] as $val){
    $item = (object)['foo' => $val];
    $heap->insert($item);
}
$obj->foo = 9; // меняем объект который уже в куче

foreach($heap as $element){
    echo $element->foo." \n";
}

echo "count=".$heap->count();

16 15 11 10 9 8 7 5 count=0

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории