Как-то у меня так получается, что целыми днями я программирую, а ничего полезного в ЖЖ от этого не появляется. (А нужно-ли вообще в ЖЖ чему-то появляться -- это другой вопрос и lleo на него недавно отвечал).
Так. Что я могу предоставить полезного... Утилита сейчас не готова и нескоро будет. Код у меня специфичный, он под Борланд и активно пользует AnsiString, то есть, непереносим, не-Борландам он нафиг не сдался. Остаётся вещать, даря крупицы премудрости всем, кто случайно наткнется на статью.
* * *
Программисту утилит придется писать две версии
Сразу напишу, почему -- не потому что плохое планирование, а потому что форматы данных заранее никогда не известны. Я вполне серьезен, заранее невозможно предсказать, можно даже не пытаться. Единственное решение, это на первую версию потратить как можно меньше времени.
Разгадка простая -- программу определяют данные.
Например: клиент-сервер. На сервере хранится база. Клиенту, в принципе, нужна только малая часть базы. Прямое подключение к базе невозможно. (Неважно почему. Такая постановка задачи.)
Сразу-же вопрос, как будет идти обмен данными -- символьными строками (как IRC), XMLRPC, бинарными пакетами, CORBA, etc. Предположим, выбирается XMLRPC. То есть, данные приходят в виде пакета, оформляются тегами, можно набить из этих тегов списки или хэши и не мучаться с типами. Одно плохо -- эти теги на 80% увеличивают объём пакета, чисто текстовой информацией, которая вне пакета не нужна. Окей, мы ведь так и планировали -- вся база не нужна, только небольшая часть, нагрузка не очень. Все, утилита написана и можно сдавать.
И тут, выясняется, что при первом запуске, утилиту надо инициализировать очень большим объемом данных, и только потом запрашивать, как планировалось, понемногу... В результате, эти 80% надолго завешивают запуск утилиты, хотя потом она работает нормально. А для того, чтобы убрать 80%, надо переходить на совершенно другую модель передачи данных. Что делать? Делать, как написано в заголовке -- писать вторую версию. Первая версия нужна была для того, чтобы наткнуться на проблему. Вторая версия уже её решает.
С другой стороны, вы у меня спросите -- а заранее нельзя было этого предсказать? Куда делось планирование проекта? Так вот. Это и было планирование. Смотрите: (1) есть работающая утилита, пусть и долго инициализирующаяся, (2) есть что тестировать, (3) найдены все подводные камни, (4) достаточно одного программиста вместо профессионального проектировщика.
Можно найти такой минус -- программист старался-старался, а теперь надо всё с начала начинать? Так это не минус, просто надо было с самого начала смириться с тем, что первый блин будет комом и не тратить на него столько времени. Надо быть либо очень-очень хорошим предсказателем всех подводных камней, либо сразу считать первую версию не для продажи, предназначенной не для упражнений в эффективном кодинге, а собственно, процесом проектирования.
Окей, второй ваш вопрос -- с какого вия это называется второй версией? Надо-же только доделать первую?
Рассмотрим тот-же пример. Предположим, задача поставлена так, что невозможно установить нормальную БД, нужно писать свою, да ещё и обязательно хранить всё в памяти. Причем, мы помним, что клиент хранит только часть базы, то есть, ему явно требуется разреженный массив. Планирование подсказывает нам, что если хранить всё в хэше, то можно будет обращаться к записям по ключам хэша и таким образом, имитировать разреженный массив. Отлично. Программист вытаскивает на свет библиотечку с хэшем, компилирует, утилита готова.
И тут оказывается, что клиент не так уж часто удаляет устаревшие данные. А поиск по всё увеличивающемуся хэшу всё медленнее и медленнее. Что делать? Программист берется показать своё мастерство и пишет отлично спроектированный менеджер ресурсов, либо... пишет новую версию, которая не использует хэш (например, деревом чисел).
То есть, если программист не смиряется с тем, что первый блин комом -- он тратит время на усовершенствования неверного решения. Хотя, достаточно подумать и найти решение верное.
Вопрос третий -- как не превратить всё это в написание третьей, четвертой и т.д. версии? Ну это простой вопрос, ответ на него тот-же что и всегда. Надо, чтобы первая версия была рабочей, тогда можно будет её тестировать. Но без излишеств, чтобы не потратить времени больше, чем требуется на планирование.
Итого. Надо сразу смириться, что то, что получится в первый раз -- это то, что называется "бета". Конечная версия -- это не доработка беты, а написанная с нуля, вторая версия утилиты.
ЗЫ Теперь остаётся только найти в википедии, кто уже это раньше придумал и что у него получилось :")))
* * *
Дерево чисел (не помню, как это называется у нормальных программистов)
Смысл этой идеи в том, что нам позарез нужен большой разреженный массив и ключами к нему являются числа (то есть, это индексы).
Сначала задаём максимальное число индекса, например, миллион. Для пояснения работы, предположим, что раньше я в него занёс индексы от 10 до 255. Добиваем до шести цифр -- от 000010 до 000255.
После этого работа идёт так -- нужен нам индекс, скажем, 156. Добиваем его до шести цифр -- 000156. Идем в дерево. Начинается оно с десяти цифр от 0 до 10. Ссылка есть только на числе 0, а остальные NULL. Ссылка на 0 ведёт к следующим десяти цифрам. И так далее: 0->0->0->1->5->6. На последней шестерке хранятся уже наши данные, можно их забирать.
То есть, понятно -- чтобы достучаться до индекса надо выполнить шесть итераций. Например, в обычном массиве нужна была-бы одна итерация, но и места он занимал-бы на весь миллион сразу и почти весь пустой. В хэше количество итераций увеличивается вместе с размером и при больших числах производит унылые задержки. Получается отличная идея для небольшой БД -- запрос выполняется с одной и той-же скоростью, почти не занимает память под пустые данные, и идеально подходит под последовательно заполняемые индексы.
ЗЫ Эту идею я прочитал где-то в книге, а где -- не помню :"(
* * *
Ох...
Надеюсь, после этого мой долг демону ЖЖ, который требует постов, выполнен. :"))
ЗЗЫ ПодCUTивать не буду, юзайте колесико мыши ^_^
_