V>> Почему с "индексом" проблемы?..
DG>индексов может и не быть, но реляционная модель будет существовать. DG>элементы же можно искать и без всяких индексов через полный пробег по множеству
Ради бога, если не забыть, что индекс — это таки выделенное отношение. С т.з. РА, "пробег" по отношению, которое мы приняли в кач-ве индекса, ничем не отличается от "пробега" по другому какому-нить другому отношению.
S>Но запуск профайлера всё равно был бы дешевле и точнее.
это верно(особенно последнее) только при совпадении множества факторов:
1. совпадают окружения при запуске профайлера и реальное окружение.
2. совпадает набор запросов подаваемый программе под профайлером и набор запросов прогоняемый в реальном окружение.
3. профайлер умеет собирать относительную (условную) статистику (или это учтено при в сценарии использования профайлера)
4. правильно зафиксировано и учтено при профайлинге, что именно оптимизируется: среднее время запроса, верхняя граница обработки запроса, достаточность быстродействия и т.д.
зы
в моем понимании, хороший программист должен уметь строить модель узких мест своих программы прямо по коду, используя профайлер лишь для проверки и корректировки своего понимания
V>Ради бога, если не забыть, что индекс — это таки выделенное отношение. С т.з. РА, "пробег" по отношению, которое мы приняли в кач-ве индекса, ничем не отличается от "пробега" по другому какому-нить другому отношению.
в самой реляционной модели и РА, пока рассматривается только корректность тех или иных операций, никаких "пробегов" еще нет, и соответственно нет индексов.
пробеги и индексы появляются, когда кроме рассмотрения корректности появляется еще рассмотрение скорости выполнения.
соответственно, ты сейчас про какую РА говоришь — ту которая рассматривает только корректность, или ту которая еще рассматривает корректность + скорость?
Здравствуйте, DarkGray, Вы писали:
S>> Так вот, согласно ECMA, эта реальная identity будет всего лишь эквивалентностью, и то лишь при условии выполнения ряда условий из определения эквивалентности.
DG>и фиг с ним. в каких сценариях это будет аукаться?
В сценариях, где можно попутать идентичность объектов. Пример: ты думал что изменил строку и на это рассчитывал в то время как она не изменилась.
DG>мы вон уже выяснили, что даже double полностью не поддерживает идентичность (рефлексивность сооблюдается только на подмножестве всех значений)
Мы выяснили что оператор (==) для double не заменяет идентичность. Но тем не менее, в ECMA определена идентичность для value типов. DG>и когда это последний раз аукалось? и в каких сценариях нельзя рассматривать double (переменную типа double) как объект?
И снова я против того что бы рассматривать переменную как объект. А по поводу double-а, отвечу, что идентичность он таки поддерживает.
DG>или возьмем реальный пример: версионный объект (двух типов). версионный объект при определенных изменениях создает версии своего состояния.
DG>объект с версионностью первого типа: создает версию, если явно его об это попросить DG>
DG>var xv = x.FixVersion();
DG>var y = x;
DG>y.Change1();
DG>
DG>во втором сценарии, версия объекта создается автоматически при изменении объекта DG>
DG>var y = x.Change1();
DG>
DG>в обоих этих сценариях появляется две плоскости: DG>ecma-объекты и логические объекты. (и те и другие удовлетворяют ОО-модели).
DG>что здесь является функцией идентичности для логических объектов?
Вот когда ты определишьь идентичность для "логических объектов", тогда и начнем "логические объекты" рассматривать в качестве объектов ОО системы. А до тех пор, они объекты по ECMA. DG>кстати, эти обе версионности являются эквивалентными: через адаптер можно одну версионность преобразовать к второй версионности, и наоборот.
Какое это имеет значение?
DG>первый вариант версионности назовем backup-версионность DG>второй вариант версионности назовем immutable-версионность
DG>immutable-версионность обладает интересным свойством: ссылка x всегда ссылается на ту версию объекта, которой была проинициализирована, вне зависимости от того, в какой момент времени был произведен реальный вызов.
ОО не знает, что такое версия объекта. Эта версия — это особенность конкретной модели. Причем, версия — самостоятельный объект ОО.
DG>и оказывается, что для сложного кода со сложными оптимизациями (lazy, создание по требованию и т.д.) удобнее работать с объектами с immutable-версионностью: потому что при lazy есть состояние неопределенности, когда произойдет реальный вызов, а immutable-версионность гарантирует, что даже несмотря на эту неопределенность поведение всегда будет одним и тем же.
DG>соответственно, подбирая под каждую неопределенность объекты с определенным поведением(контрактом) можно последовательно сделать так, чтобы неопределенности не мешали выдавать определенное поведение.
Удобнее не связывать lazy с мутабельными сущностями, тогда голова не будет болеть, lazy ли, иммутабл ли, или и то и другое одновременно. И никаких необпределенностей.
S>> Вот послал я объекту сообщение, изменяющее состояние, а почему-то объект с той же "реальной" identity на тысяче остальных клиентов, на это не среагировал. Ну и причем тут ООП?
DG>отличное ООП, просто в контракте на такое сообщение написано, что сообщение может не дойти.
А никакого сообщения тем объектам не посылалось. Согласно ООП оно должно быть послано одному объекту, и все остальные объекты с same identity должны быть неотличимы от тому, которому послали. Но беда в том, что изменив объект на одном клиенте, он не изменится автоматом на сервере, в БД, и на тысяче других клиентов. И если это так, то с такой распределенной identity какая-то фигня.
DG>и отдельно оговаривается, что происходит если не дошел запрос к объекту, и отдельно, если не дошел ответ от объекта.
someObject.UpdateState();
Запрос дошел, ответ получен. Но на 1000е клиентов что-то не так...
DG>и при этом простую ООП-архитектуру можно строить даже поверх таких особенностей(ограничений).
Ты используешь ООП архитектуру для построения некой своей архитектуры, которая имеет отношение к ООП лишь тем что "все есть объект" и построено поверх ООП системы.
DG>тут, кстати, опять же помогают объекты с версионностью второго типа, когда мы четко знаем, какая ссылка на какую версию объекта ссылается. для таких объектов код для разрешения потери сообщения через несколько повторов сообщения пишется элементарно (делаем допущение, что потеря сообщения формирует исключение, в том числе и через клентский-timeout, если ответ не пришел через заданное время): DG>
DG>var y = x.Try(3, _=>_.Change1());
DG>static T Try<T>(this T x, int count, Func<T, T> action)
DG>{
DG> for (int i = 0; i < count; ++i)
DG> {
DG> try
DG> {
DG> return Action(x);
DG> }
DG> catch (Exception exc)
DG> {
DG> if (i == count - 1)
DG> throw;
DG> }
DG> }
DG> throw new ArgumentException("count");
DG>}
DG>
DG>для объектов без версионности, или с backup-версионностью — рассмотрение всех вариантов (сообщение не дошло; сообщение дошло, но объект отказался его обрабатывать(вернул исключение); не дошел ответ и т.д.) и написание кода для корректной обработки всех вариантов — это очень сложная задача, чем обычно и пренебрегают, что видно на реальных программах.
Вообще говоря, в распределенных системах (где сообщение может не дойти туда и обратно), если не используется message passing style, то есть аналог RPC, т.е. запрашивающий знает о том, был ли ответ или исключение. Но со стороны отвечающей стороны никакая версионность не поможет, т.к. отвечающая сторона не может знать, дошел ли ее ответ до запрашивающей, если запрашивающая сторона не вышлет сообщение, подвтерждающее получение ответа. Но запрашивающая сторона может не знать, получила ли отвечающая сторона подтверждение...
Здравствуйте, Sinclair, Вы писали:
V>>Таки настаиваю. Понимаешь, индекс можно построить даже по данным, которые не поддерживают операцию сравнения, хоть этого нельзя конкретно в MS SQL, но это лишь подробности MS SQL. Принципиально в таком индексе будет то, что объем данных проекции может быть гораздо меньше объема всех данных, поэтому операция выборки/ограничения по индексу может быть выполнена многократно эффективнее, чем по всем исходным данным. Вот так может приниматься решение — делать индекс кластерным или некластерным. S>Вы напрасно спорите с очевидным. Если мы рассуждаем исключительно в терминах РА, то нет никакого смысла в "сохранении" результата какой-то операции, т.к. там нет понятия "эффективности".
Это ты откуда берешь? В терминах РА мы всегда выполняем некую последовательность операций, где последующие операции используют результаты предыдущих. Это классическая императивная последовательность действий. Но, доказано, что РА и реляционное исчисление взаимно эквивалентны, т.е. декларативные формулы реляционного исчисления всегда могут быть выражены через императив реляционной алгебры. Вспомним ниже, когда дойдем до SQL.
Насчет эффективности — я даже не знаю, как можно было не понять, о чем речь. Что не так с сохранением частоиспользуемых операций? И повторюсь: для операций РА эффективность является вычислимой. Т.е. берем конкретную операцию из РА, берем некую структуру данных... так вот, для этой пары {операция РА, структура данных} обязательно есть оценка стоимости в терминах K*O(n). И опять же повторюсь, именно так работает оптимизатор, он же не на кофейной гуще гадает...
S>Если мы рассуждаем в терминах RDBMS, то операции "проекция" недостаточно, по двум причинам: S>1. Индекс, помимо "публичных" данных, которые можно получить в результате проекции, хранит обратные ссылки на "строки таблицы". В РА невозможно сослаться на конкретную строку.
Садись, два.
Выделенное неверно. Далее все рассуждения, основанные на этом — тоже. Гуглить по фразе "кортеж однозначно определяется", до кучи можно еще "суррогатный ключ". Понимаешь... в общем, лень толкать банальности, но невозможно вынести из отношения ключ (в общем случае составной) без ввода в процессе декомпозии дополнительного атрибута в оба получившихся отношения для службы в кач-ве суррогатного ключа. Или тебя смущает, что внутренний ключ-bookmark для тебя недоступен? Меня не смущает, коль я знаю, как именно происходит декомпозиция отношений.
S>2. Индекс, помимо "содержания" данных, обладает особенностями их размещения, которые позволяют некоторые операции выполнять быстрее.
Это не важно, для выбора того или иного плана запроса нам от структуры необходима лишь оценка стоимости некоей операции РА над ней, а вовсе не подробности ее реализации. Считай любую структуру черным ящиком с известными характеристиками по каждой операции из РА.
S>В частности, поиск значения ключа в индексе традиционно выполняется за O(log(N)) либо O(N/M), с достаточно большими основаниями логарифма или M для того, чтобы в практических случаях это сводилось к O(1). Некоторые виды индексов также позволяют делать c подобной асимптотикой операции диапазонного поиска.
Плевать, есть разные индексы. В хеш-таблице у меня будет близко к O(n), но это всё не принципиально в нашем обсуждении.
S>Кстати, индекс для данных, не поддерживающих операции сравнения, не имеет никакого смысла.
Имел ввиду операцию сравнения на больше/меньше, конечно, которая обязательная для выполнения индексов в виде деревьев для упомянутого случая MS SQL. Ес-но, операция на равенство в домене должна быть, иначе смысл в индексе на таком домене пропадает, это и так понятно.
V>>Еще раз большими буквами — любой некластерный индекс — это и есть проекция. В классике индексы некластерные изначально. Просто в MS SQL ввиду особенностей хранения блобов кластерные индексы оч популярны. S>Вы продолжаете писать бессмысленный набор слов. Популярность кластерных индексов в MS SQL никак не связана с особенностями хранения блобов, да и вообще с блобами не связана.
Таки настаиваю, потому как встречал разные БД в свое время, в том числе такие, где индексы выделялись как некластерные исключительно для улучшения K при O(n), ввиду банально меньших данных, требуемых для сканирования. А в MS SQL строки таблиц с кластерным индексом имеют фиксированную длину, именно для этого блобы, выше определенной длины, не хранятся в самих таблицах. Их можно разместить где угодно, хоть на других жестких дисках. Поэтому... поэтому просто прочти еще раз, что я там написал. Кстати, неплохая вышла иллюстрация побочного эффекта, возникающего при использовании пропагандируемого подхода, что "необязательно понимать устройство того, с чем работаешь". Не объяснишь, как же ты в своих проектах принимаешь решение, делать некие индексы кластерными или нет? Мне уже очень любопытно услышать этот алгоритм рассуждений.
V>>Я тебе скажу так, в достаточно большой системе, с многими миллионами записей движений и сотнеями справочников, одно лишь только изменение суррогатных ключей с типа int на shortint в справочниках и оформление индексов как некластерных у справочников, где записи достаточно большие (много полей) подняло производительность более чем в четверо. Вот зачем нужна проекция при построении индекса — это снижение объема перелопачиваемых данных при операциях над таблицами, проводимыми по этому индексу/ключу (фактически все операции из РА). S>Я вас разочарую: снижение объема перелопачиваемых данных в индексах выполняется не за счёт операций проекции, а за счёт организации данных.
Ну что ж, так и думал... тебе был дан пример улучшения К при O(n) при всех других прочих равных. Т.е. индекс УЖЕ был, мы лишь вынесли его за пределы остальных данных таблицы и минимизировали объем данных индекса, в итоге получили нифига себе какой профит. Ты понял, что произошло? В терминах O(n) кластерный индекс эквивалентен двоичному дереву, поэтому вынос его за пределы конкретно в MS SQL не изменяет вид характеристики O(n), это была лишь демонстрация того, для чего вообще нужны некластерные индексы и почему пренебрегать К при O(n) вовсе не стоит. А ты не понял примера. Так что, предыдущий вопрос, относительно принятия решений по индексам в твоих проектах, остается в силе.
V>>Наверно не понимаешь, что есть реляционное исчисление, а что есть реляционная алгебра, так? Это совсем не одно и то же. S>И тем не менее, SQL не оперирует понятиями реляционной модели.
Тем не менее, классический SQL оперирует понятиями реляционного исчисления + непосредственно поддерживает некоторые операции РА, а кое-какие диалекты поддерживают еще больше операций РА, чем даже классический SQL-92.
Т.е. конструкции SQL-92 могут однозначно отображаться на язык реляционного исчисления. Обратно неверно, т.к. в реляционном исчислении больше возможностей, чем в SQL-92. Но уже Oracle SQL или Transact SQL имеют чуть большую область взаимного отображения, покрывая целиком реляционное исчисление, + дают возможность выполнять произвольные операции из РА (пусть даже эмулируя их вручную на курсорах и временных таблицах) и вводя еще больше ср-в уже за рамками реляционной модели, в основном за счет всяких императивных конструкций и свободных+внешних ф-ий.
Вот на пальцах разница м/у РА и реляционным исчислением (прямо с первой страницы гугла): http://www.mstu.edu.ru/study/materials/zelenkov/ch_4_5.html
Формулы реляционного исчисления по ссылке даны по-русски, но есть другие известные языки, например QUEL и ALPHA, введенный Коддом. Хотя, они выглядят близко к тому, что в примере, только на английском.
Еще из первой страницы гугла про реляционное исчисление: http://www.ref.by/refs/67/28689/1.html
Эта ссылка напомнила мне краткий конспект того, как именно оно преподавалось нам когда-то.
V>>Я не знаю, что есть логическое, а что есть физическое в твоем понимании? S>Это я вижу. Поясняю: При рассмотрении анатомии оптимизаторов запросов в СУБД, выделяют два вида "планов запроса": S>1. Логический план. Выражается в терминах операций расширенной РА; является результатом синтаксического разбора SQL запроса и некоторой предварительной оптимизации. Предварительные оптимизации на этом этапе имеют целью упрощение плана для дальнейшего анализа и устранение заведомых неоптимальностей. S>2. Физический план. Выражается в терминах императивных операций, работающих над конкретными объектами реляционной базы. Это совсем другие операции. Скажем, там, где в логическом плане была пара операций π и σ, в физическом плане будет одна операция table scan. Или одна операция index seek. Или операция index scan и операция bookmark lookup.
Улыбнуло.
Index scan — это по прежнему операция ограничения из РА, а bookmark lookup — один из видов того самого соединения. Похоже, разный уровень подробностей происходящего застилает от тебя суть вещей... ИМХО, это от того, что ты представляешь себе индексы не как декомпозицию исходного отношения, а нечто "монолитное" (С), присущее данным. Представь индекс как отдельное отношение и всё сразу встанет на свои места. И тогда физический уровень будет уровень формата данных разве что, т.е. именно физическое размещение данных во внешней и оперативной памяти. Потому как ты натурально оперируешь всё еще логическими уровнями разной степени подробности... Так и подумал изначально, поэтому переспросил. Собсно, вот пример абстракций с разной степенью подробностей, о чем мы и спорили изначально, еще до сваливания в тему СУБД.
V>>Использование разного порядка сканирования индексов — это физическое отличие или логическое? S>Конечно же это отличие физического плана. В логическом плане никаких индексов нет.
Сорри, но выделеное профанирует вообще весь спор об абстракциях.
Давай тогда уже так: что есть абстракция на твой взгляд? Может, мы спорим "каждый о своем"? Натурально обидно после стольких постов увидеть, что "в логическом плане никаких индексов нет", это же сколько потраченного времени...
S>В реляционной алгебре нет никаких императивных операций. RTFM.
Угу, смотрю в книгу, вижу известно что. Короче, преобразования данных, выполняемых в терминах РА — это ВСЕГДА императивный алгоритм, построенный на примитивах-операциях РА. Важна последовательность операций, а сами аргументы операций — это результаты (в общем случае) предыдущих операций. Таки решение хотя бы пары десяток задач по РА настоятельно рекомендуется, для прочистки... А до тех пор мы будем обсуждать все эти ньюансы крайне поверхностно. (хоть и с демонстрируемым непонятно откуда пафосом)
Здравствуйте, DarkGray, Вы писали:
V>>Ради бога, если не забыть, что индекс — это таки выделенное отношение. С т.з. РА, "пробег" по отношению, которое мы приняли в кач-ве индекса, ничем не отличается от "пробега" по другому какому-нить другому отношению.
DG>в самой реляционной модели и РА, пока рассматривается только корректность тех или иных операций, никаких "пробегов" еще нет, и соответственно нет индексов. DG>пробеги и индексы появляются, когда кроме рассмотрения корректности появляется еще рассмотрение скорости выполнения.
DG>соответственно, ты сейчас про какую РА говоришь — ту которая рассматривает только корректность, или ту которая еще рассматривает корректность + скорость?
Про "пробег" сказал ты, имея ввиду наверно способы реализации операции "ограничение" (или "ограничения" как часть некоей теоретико-множественной операции РА, т.е. помним что такие операции могут быть выражены через другие операции РА, что принципиально). Т.к. конкретный способ "пробега" не задан, это ничему из РА не противоречит.
Я лишь ответил, что если считать выделение индекса как декомпозицию отношений в классичесской реляционной модели, то твой "пробег" по индексу, т.е. выделенной части декомпозиции, с целью того самого ограничения, ничем не отличается от "пробега" по исходному отношению. Это будет всегда верно в случае корректности проведенной декомпозиции, т.е. такой декомпозиции, которая делает верными все зависимости и ограничения некоей исходной схемы. Напомню, что зависимости исходной схемы всегда задаются как зависимости м/у аттрибутами, а вовсе не отношениями. Простейший пример: есть некая схема R {ABCD}, и заданы зависимости A->B, B->CD. Для этой схемы будет уместна декомпозиция {AB, BCD}, причем, в реальной СУБД мы во втором отношении можем создать индекс B, сугубо эффективности ради, но! это будет означать лишь еще раз произвести декомпозицию по всем правилам декомпозиций с вводом специального аттрибута-ключа B#, для требований сохранения исходной зависимости B->CD транзитивно через B->B#, B#->CD. В итоге получим декомпозицию заданной схемы в виде: {AB, BB#, B#CD}.
В общем, по данной выше ссылке я попытался продраться через всевозможные предрассудки и поверхностность... я бы уже с этой "терминологической борьбой" завязывал бы, потому как в качестве ликбеза пора бы начинать постить сюда и решать пошагово задачи по реляционному исчислению и реляционной алгебре.
DG>вычислительное узкое место в этом сравнении DG>
DG> return from line in FileLines(dictionary)
DG> where line.Length == originalRack.Length
DG> where racks.Contains(Canonicalize(line))
DG> select line;
DG>
DG>сложность: 27 вызовов * кол-во слов в словаре с заданной длиной * (sort слова + (1+26 * кол-во '?') сравнений слов) DG>И скорее всего именно поэтому его уже пытались оптимизировать (вынесен racks и добавлено сравнение длин). DG>racks стоит заменить на Set/Dictionary вместо массива
А стоимость самого получения racks не изучал? Мне навскидку показалось, что размер racks будет относительно небольшой в большинстве случаев (сотни элементов в среднем), но дорогой в получении.
Здравствуйте, DarkGray, Вы писали:
G>> б)если А иднетичен Б, то любое изменение А сразу отражается на Б. Это и есть определение ОО-идентичности.
DG>гон и провокация, и опять же нарушение инкапсуляции. мы не можем утверждать когда именно оно применится, мы можем лишь делать утверждения на основе наблюдамого поведения.
Не в этом дело. Дело в том что совпадение identity в ООП говорит о том что это один и тот же объект, и свойство, описанное выше в данном случае тривиально и очевидно.
DG>и правильная формулировка: в ООП объект А и объект Б считаются одним и тем же(идентичными), если конкретное поведение объекта А и конкретное поведение объекта Б не отличимо друг от друга.
Нет, это ты привел определение эквивалентности. Для отношение идентичности требуется чтобы оно от поведения не зависело. http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
Исследования для одного из случаев...
Опять же, для первой итерации потянет. Пример подробно не смотрелся... так же сказалось отсутствие навыков беглого чтения LINQ (почти не юзаем в работе), есть такое. Если взглянуть внимательней, то racks.Contains() — действительно жесть... Там напрашивается ровно обратное сравнение: allWords[result.Length].ContainsKey(result), происходящее еще на этапе ReplaceQuestionMarks.
Здравствуйте, DarkGray, Вы писали:
S>>Но запуск профайлера всё равно был бы дешевле и точнее.
DG>это верно(особенно последнее) только при совпадении множества факторов: DG>1. совпадают окружения при запуске профайлера и реальное окружение. DG>2. совпадает набор запросов подаваемый программе под профайлером и набор запросов прогоняемый в реальном окружение. DG>3. профайлер умеет собирать относительную (условную) статистику (или это учтено при в сценарии использования профайлера) DG>4. правильно зафиксировано и учтено при профайлинге, что именно оптимизируется: среднее время запроса, верхняя граница обработки запроса, достаточность быстродействия и т.д.
DG>зы DG>в моем понимании, хороший программист должен уметь строить модель узких мест своих программы прямо по коду, используя профайлер лишь для проверки и корректировки своего понимания
Прочитай пост Липперта по ссылке:
* Set meaningful, measurable, customer-focused goals.
* Write the code to be as clear and correct as possible.
* Carefully measure your performance against your goals.
* Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, whatever.
* If you did not meet your goal, use tools to discover what the worst-performing fixable thing is, and fix it.
Нету здесь пункта "строить модель узких мест". Если в коде еще есть ленивость и\или асинхронность, то единственный способ — мерить. Даже предполагать что-то нельзя.
V>А стоимость самого получения racks не изучал? Мне навскидку показалось, что размер racks будет относительно небольшой в большинстве случаев (сотни элементов в среднем), но дорогой в получении.
там сложность примерно: кол-во возвращаемый слов * (~2 пробега по слову + 2 копирования слова + кол-во '?' * прокрутка "такта" enumerable)
кол-во возвращаемых слов зависит экспонециально от кол-ва '?': 26^кол-во '?'
итого сложность в обработанных символах:~4*длина запроса*26^кол-во '?'
соответственно, пока кол-во '?' небольшое 0-3, то вклад будет небольшим по сравнению с пробегом по 2мб словаря.
Здравствуйте, gandjustas, Вы писали:
G>Прочитай пост Липперта по ссылке:
G>
G>* Set meaningful, measurable, customer-focused goals.
G>* Write the code to be as clear and correct as possible.
G>* Carefully measure your performance against your goals.
G>* Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, whatever.
G>* If you did not meet your goal, use tools to discover what the worst-performing fixable thing is, and fix it.
G>Нету здесь пункта "строить модель узких мест". Если в коде еще есть ленивость и\или асинхронность, то единственный способ — мерить. Даже предполагать что-то нельзя.
Это верно в той области ПО, для которой эффективность не является конкурентным преимуществом. Например, для заказного ПО, там же никакой конкуренции... Нужна лишь некая "достаточная" производительность.
А в коробочном ПО в реальности бывает так, что профайлер показывает до 30% затрат на всего одну из самых затратных операций, но она никак не оптимизируема, всё, упёрлись в предел. Зато остальное можно подтянуть, то самое, которое 1-2% каждое в среднем, но примерно вдвое общую эффективность поднять, подняв каждую из мелочей многократно. Это из реальной практики... Для каждого такого случая нужны банально идеи, бо показания профайлера тебе код не напишут.
Есть еще момент: эффективность не всегда определяется пропускной способностью, зачастую идет требования минимизации latency (у нас по работе, например), а в этом деле, когда речь идет о единицах микросекунд, профайлерами уже и близко не пахнет.
G>* Set meaningful, measurable, customer-focused goals.
G>* Write the code to be as clear and correct as possible.
G>* Carefully measure your performance against your goals.
G>* Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, whatever.
G>* If you did not meet your goal, use tools to discover what the worst-performing fixable thing is, and fix it.
не вижу где написано, что программист не должен уметь оценивать производительность своего кода без профайлера.
G>Если в коде еще есть ленивость и\или асинхронность, то единственный способ — мерить. Даже предполагать что-то нельзя.
это лишь означает, что некоторые не умеют готовить ленивость или асинхроность.
зы
и на всякий случай напишу очевидные вещи:
1. через профайлер можно прогнать лишь ограниченное кол-во сценариев, которое много меньше, чем поддерживаемое программой кол-во сценариев
2. bottleneck необходимо уметь обнаруживать до того, как на него наткнутся в реальном применении (особенно это актуально для защиты от DDOS)
G>>* Set meaningful, measurable, customer-focused goals.
G>>* Write the code to be as clear and correct as possible.
G>>* Carefully measure your performance against your goals.
G>>* Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, whatever.
G>>* If you did not meet your goal, use tools to discover what the worst-performing fixable thing is, and fix it.
DG>не вижу где написано, что программист не должен уметь оценивать производительность своего кода без профайлера.
Не написано что должен, следовательно не должен. Элементарная логика.
Более того, не всегда приходится свой код оптимизировать.
G>>Если в коде еще есть ленивость и\или асинхронность, то единственный способ — мерить. Даже предполагать что-то нельзя.
DG>это лишь означает, что некоторые не умеют готовить ленивость или асинхроность.
Счегобы? Многие умеют писать программы используя ленивость и асинхронность. Далеко не все могут предположить по внешнему виду время работы.
Пример на форуме показал это очень явно. Даже местные гуры перформанса не смогли сходу обнаружить проблему. Так в коде не было ни ленивости, ни асинхронности, ни десятка уровней косвенности.
DG>зы DG>и на всякий случай напишу очевидные вещи: DG>1. через профайлер можно прогнать лишь ограниченное кол-во сценариев, которое много меньше, чем поддерживаемое программой кол-во сценариев DG>2. bottleneck необходимо уметь обнаруживать до того, как на него наткнутся в реальном применении (особенно это актуально для защиты от DDOS)
Еще раз читай то что я процитировал. Первый пункт.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, gandjustas, Вы писали:
G>>Прочитай пост Липперта по ссылке:
G>>
G>>* Set meaningful, measurable, customer-focused goals.
G>>* Write the code to be as clear and correct as possible.
G>>* Carefully measure your performance against your goals.
G>>* Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, whatever.
G>>* If you did not meet your goal, use tools to discover what the worst-performing fixable thing is, and fix it.
G>>Нету здесь пункта "строить модель узких мест". Если в коде еще есть ленивость и\или асинхронность, то единственный способ — мерить. Даже предполагать что-то нельзя.
V>Это верно в той области ПО, для которой эффективность не является конкурентным преимуществом. Например, для заказного ПО, там же никакой конкуренции... Нужна лишь некая "достаточная" производительность.
Да-да-да. Забавная байка. У тебя есть сведения о корреляции производительности и продаж для определенного класса программ? Уверен что нет, тогда зачем ты продолжаешь повторять то что не доказано?
С другой стороны "достаточная производительность" явно вытекает из экономической целесообразности: нем смысла тратить на оптимизацию больше чем нужно.
V>А в коробочном ПО в реальности бывает так, что профайлер показывает до 30% затрат на всего одну из самых затратных операций, но она никак не оптимизируема, всё, упёрлись в предел. Зато остальное можно подтянуть, то самое, которое 1-2% каждое в среднем, но примерно вдвое общую эффективность поднять, подняв каждую из мелочей многократно. Это из реальной практики... Для каждого такого случая нужны банально идеи, бо показания профайлера тебе код не напишут.
А ты вообще прочитал то что я процитировал? В 5 пункте fixable слово видел?
V>Есть еще момент: эффективность не всегда определяется пропускной способностью, зачастую идет требования минимизации latency (у нас по работе, например), а в этом деле, когда речь идет о единицах микросекунд, профайлерами уже и близко не пахнет.
А чем пахнет? ты ведь как-то меряешь этот самый latency или ты по коду пытаешься его угадать?