Re[9]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.09.08 11:10
Оценка: 26 (1) +2 -3
Здравствуйте, criosray, Вы писали:
C>Вы считаете, что Вы знаете что такое leaky abstractions?
Да, считаю.

S>>Абстракции в архитектуре есть всегда. Вообще вся архитектура — это выбор абстракций. Ты имел в виду, что любая абстракция может стать leaky?

C>Конечно.
C>Вы это серьезно? Ну и фантазия у Вас...
При чем здесь фантазия? Мальчик, сходи почитай хотя бы одноименную статью Спольски.

Поясняю для смелых подростков, на пальцах, что значит leaky в применении к lazy loading.

Весь смысл lazy loading — в том, чтобы спрятать от его пользователя информацию о том, когда именно происходит загрузка данных. Если программист видит, где именно происходит loading, то LL облажался. LL делает вид, что order.Items уже здесь и сейчас, а на самом деле они все еще в базе, и будут запрошены только когда я начну итерироваться по Items.

Ну так вот его leakyness состоит в том, что на самом деле есть существенная разница между "здесь и сейчас" и "всё еще в базе". Функционально разницы нет. А вот с точки зрения производительности — разница есть. И когда я буду делать вызов order.Items[i].StockItem.Name, он легко приведет к отдельному запросу на каждой итерации. И протечка будет ровно в том, что это приведет к чудовищной производительности данного решения. Это 100% аналог проблемы с конкатенацией строк, которую приводит Спольски.

И все способы борьбы с вот этой вот протечкой — это фактически отказ от абстракции. Вместо того, чтобы наивно итерироваться по order.Items, я буду должен отдать специальный cache hint и заставить ORM всё-таки залоадить данные энергичным способом. То есть никакого Lazy load уже нет, уже есть "forced lazy load". Всё, это и был щасливый конец LL.

Понимание причин протекания абстракции "persistence ignorance" оставляю в качестве домашнего задания.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Взаимодействие с Базой Данных из C# по схеме MS
От: criosray  
Дата: 16.09.08 13:33
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>>>Абстракции в архитектуре есть всегда. Вообще вся архитектура — это выбор абстракций. Ты имел в виду, что любая абстракция может стать leaky?

C>>Конечно.
C>>Вы это серьезно? Ну и фантазия у Вас...
S>При чем здесь фантазия? Мальчик, сходи почитай хотя бы одноименную статью Спольски.

S>Поясняю для смелых подростков, на пальцах, что значит leaky в применении к lazy loading.


Во-первых, смените тон, уважаемый. Я Вас кажется не оскорблял. Во-вторых, то, что пишите Вы не имеет ничего общего с leaky abstractions. Садитесь — два.
Re[11]: Взаимодействие с Базой Данных из C# по схеме MS
От: IB Австрия http://rsdn.ru
Дата: 16.09.08 14:32
Оценка: -1 :)
Здравствуйте, criosray, Вы писали:

C>Я Вас кажется не оскорблял.

Ты просто не заметил...

C>Во-вторых, то, что пишите Вы не имеет ничего общего с leaky abstractions.

То что у тебя с терминологией бедулька — уже давно понятно.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 16.09.08 15:56
Оценка: +1 -2 :)
Здравствуйте, Sinclair, Вы писали:

S>Ну так вот его leakyness состоит в том, что на самом деле есть существенная разница между "здесь и сейчас" и "всё еще в базе". Функционально разницы нет. А вот с точки зрения производительности — разница есть. И когда я буду делать вызов order.Items[i].StockItem.Name, он легко приведет к отдельному запросу на каждой итерации.

Не приведёт. Стандартно для LL — загружать сразу всю коллекцию Items. Так что такой код будет работать вполне прилично.

У меня вообще ощущение, что если возникают проблемы с LL, то стоит посмотреть не делаем ли мы в коде слишком много лишних действий.
Sapienti sat!
Re[11]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 16.09.08 19:41
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Не приведёт. Стандартно для LL — загружать сразу всю коллекцию Items. Так что такой код будет работать вполне прилично.

C>У меня вообще ощущение, что если возникают проблемы с LL, то стоит посмотреть не делаем ли мы в коде слишком много лишних действий.
И с чем товарищ IB не согласен?
Sapienti sat!
Re[12]: Взаимодействие с Базой Данных из C# по схеме MS
От: IB Австрия http://rsdn.ru
Дата: 16.09.08 20:43
Оценка: 2 (1)
Здравствуйте, Cyberax, Вы писали:

C>И с чем товарищ IB не согласен?

Во-первых, товарищ Cyberax, с тем, что загружать сразу все Items — тоже не лучший вариант для LL, все они могут быть просто не нужны, а нужна лишь часть, отобранная по какому-либо критерию, так что хрен редьки не слаще.
А во-вторых, проблемы начинаются гораздо раньше — не когда LL перестал справляться, а когда не нашли лучшего варианта, чем использовать LL. Собственно, повторю еще раз мысль, уже не однократно озвученную здесь Тохой — LL и ORM-ный кеш служат не для решения проблем приложения, а для решения проблем самой ORM.
ORM, если абстрагироваться от ненужных подробностей — это попытка натянуть на глобус резиновое изделие номер два. Если в конкретном приложении удобно иметь дело с ОО-данными — ставьте полноценную ООБД и не парьте мозг окружающим, половина проблем снимется сразу. Если же хранилище, по каким-то причинам должно быть реляционным, то ORM, которое пытается навернуть объекты на данные, вынуждено прибегать к помощи озвученных LL, кешей и прочих ритуальных приседаний. Если же мы пытаемся использовать ORM по правильному (я вполне верю, что гибернейт с этим отлично справляется =) ), то на зачем оно нам вообще нужно, если с той же задачей те же L2S, BLT и т. д., справляются не хуже?
Безусловно, существует класс приложений, где использование подобного рода инструментов вполне оправдано (но, к слову, там это как правило довольно критичный участок, который все равно пишется отдельно под конкретную задачу), но это скорее исключение. А для большинства рядовых решений использование ORM-ов скорее вредит, так как тащит кучу лишнего кода и провоцирует кривую архитектуру.
Мы уже победили, просто это еще не так заметно...
Re[13]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 16.09.08 21:18
Оценка: +1
Здравствуйте, IB, Вы писали:

C>>И с чем товарищ IB не согласен?

IB>Во-первых, товарищ Cyberax, с тем, что загружать сразу все Items — тоже не лучший вариант для LL, все они могут быть просто не нужны, а нужна лишь часть, отобранная по какому-либо критерию, так что хрен редьки не слаще.
Если нужна часть — то обычно её загружают отдельно (запросом, например). Так что загрузка все коллекции — это прекрасно работающая консервативная стратегия.

IB>А во-вторых, проблемы начинаются гораздо раньше — не когда LL перестал справляться, а когда не нашли лучшего варианта, чем использовать LL. Собственно, повторю еще раз мысль, уже не однократно озвученную здесь Тохой — LL и ORM-ный кеш служат не для решения проблем приложения, а для решения проблем самой ORM.

Опять абсолюты. На практике (лично мне), например, очень часто удобно запросом выделить нужные объекты и работать с ними. LL работает тут как удобный "парашют" для тех случаев, когда нужно взять несколько незагруженных объектов.

И обычно такая стратегия прекрасно работает. Если она перестаёт прекрасно работать — то начинаем оптимизировать начальную загрузку. Т.е. начинаем оптимизацию, когда она mature.

Кстати, возможны и ситуации, когда LL экономит время. Например, если нам достоверно известно, что в ходе выполнения метода понадобится подгрузить всего несколько объектов. Но невозможно заранее сказать каких.

IB>Если же хранилище, по каким-то причинам должно быть реляционным, то ORM, которое пытается навернуть объекты на данные, вынуждено прибегать к помощи озвученных LL, кешей и прочих ритуальных приседаний. Если же мы пытаемся использовать ORM по правильному (я вполне верю, что гибернейт с этим отлично справляется =) ), то на зачем оно нам вообще нужно, если с той же задачей те же L2S, BLT и т. д., справляются не хуже?

В том-то и дело, что справляются хуже. На практике нужна смесь реляционного и объектного подхода.

По историческим причинам так получилось, что лучше всего для этого сейчас подходят RDB+ORM. Возможно, OODB+РБД-расширения подошли бы лучше, но на рынке сейчас нет таких комбинаций за нормальную цену (т.е. $0) и с нормальным качеством.

IB>Безусловно, существует класс приложений, где использование подобного рода инструментов вполне оправдано (но, к слову, там это как правило довольно критичный участок, который все равно пишется отдельно под конкретную задачу), но это скорее исключение.

Все мои приложения под этот класс подходят. Обычно на ORM прекрасно пишется 95% кода, с остальными 5% в виде ручного SQL.
Sapienti sat!
Re[14]: Взаимодействие с Базой Данных из C# по схеме MS
От: IB Австрия http://rsdn.ru
Дата: 16.09.08 21:46
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Если нужна часть — то обычно её загружают отдельно (запросом, например). Так что загрузка все коллекции — это прекрасно работающая консервативная стратегия.

Ага, здесь играем, здесь не играем, а здесь я рыбу заворачивал.. =)

C>На практике (лично мне), например, очень часто удобно запросом выделить нужные объекты и работать с ними.

Вот именно, только причем тут LL?

C>LL работает тут как удобный "парашют" для тех случаев, когда нужно взять несколько незагруженных объектов.

На практике, необходимость такого парашюта означает, что ты просто чего-то не додумал.

C> Т.е. начинаем оптимизацию, когда она mature.

Только мы premature приволокли большую пушку в виде ORM и думаем, как бы использовать все ее красивые возможности, а потом оптимизируем последствия..

C> Например, если нам достоверно известно, что в ходе выполнения метода понадобится подгрузить всего несколько объектов. Но невозможно заранее сказать каких.

Что мешает явно подгрузить, когда станет известно?

C>В том-то и дело, что справляются хуже.

Чем?

C> На практике нужна смесь реляционного и объектного подхода.

А вот здесь отлично себя показывает Linq — не linq2SQL, а просто Linq и порочая функциональщина, и ORM тут совершенно непричем, это уже не их зона ответственности.

C>Все мои приложения под этот класс подходят. Обычно на ORM прекрасно пишется 95% кода, с остальными 5% в виде ручного SQL.

Ага, ты, помнится, хвастался, как пол гибернейта под свою задачу переписал.
Мы уже победили, просто это еще не так заметно...
Re[11]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 02:59
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Не приведёт. Стандартно для LL — загружать сразу всю коллекцию Items. Так что такой код будет работать вполне прилично.

Ты, наверное, не заметил, что Items — это OrderItems. Каждая, естественно, указывает на отдельную StockItem. И вот тут и начинаются чудеса в решете.
C>У меня вообще ощущение, что если возникают проблемы с LL, то стоит посмотреть не делаем ли мы в коде слишком много лишних действий.
Всё как раз наоборот: чтобы с LL проблем не было, придется делать лишние действия.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 02:59
Оценка:
Здравствуйте, criosray, Вы писали:
C>Во-первых, смените тон, уважаемый. Я Вас кажется не оскорблял. Во-вторых, то, что пишите Вы не имеет ничего общего с leaky abstractions. Садитесь — два.
Отлично. Статью не читал, значения терминов придумываешь сам. Вместо аргументов будем, значит, фокусироваться на моем тоне. Удачи. Троллей тут игнорят.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 03:16
Оценка: 6 (1) +3
Здравствуйте, Cyberax, Вы писали:

C>Опять абсолюты. На практике (лично мне), например, очень часто удобно запросом выделить нужные объекты и работать с ними. LL работает тут как удобный "парашют" для тех случаев, когда нужно взять несколько незагруженных объектов.

Это очень дорогой парашют. Лично мне он больше напоминает мышеловку.
C>И обычно такая стратегия прекрасно работает. Если она перестаёт прекрасно работать — то начинаем оптимизировать начальную загрузку. Т.е. начинаем оптимизацию, когда она mature.
Что значит "когда она mature"? Я вижу два варианта трактовки "LL optimization maturity":
1. Мы наконец поняли, какие объекты мы трогаем в рамках часто используемых use-case, и специальными хинтами вынуждаем ORM выполнить раннюю загрузку
2. Мы убедились, что на реальных объемах LL ведет себя отвратительно, в отличие от нашей тестовой базы с 17 объектами, и заказчик стоит с топором у нас за плечами.
В итоге, мы имеем отсутствие LL на основных путях работы системы (и наш код эквивалентен загрузке датасетов с точностью до синтаксиса), и всё еще неприлично тормозную реализацию редких юз-кейзов.

C>Кстати, возможны и ситуации, когда LL экономит время. Например, если нам достоверно известно, что в ходе выполнения метода понадобится подгрузить всего несколько объектов. Но невозможно заранее сказать каких.

Не понял. Где экономия-то? Если нам невозможно сказать заранее, каких объектов, то мы просто будем вынуждены их загружать.
А вообще, ситуация "невозможности заранее" в некотором смысле искусственная. Это опять про девиации сознания, вызванные инструментом.
Поясню тезис: когда приложение проектирует программист-реляционщик, он всё время мыслит в терминах РСУБД и запросов. Когда ему нужно отбирать объекты по сложному критерию, он сразу думает о дополнительном поле (возможно, вычисляемом). Если ему нужно выводить произвольно отсортированный список, он придумает дополнительное поле "порядок для вывода". Связный список будет последним, что он станет рассматривать — потому что для его доставания нужно O(N) запросов.

Классический ООП программист думает наоборот: подсознательно он считает самой долгой операцией поиск, а самой быстрой — разыменование указателя. ОРМ поддерживают в нем эту иллюзию; в итоге он конструирует навигационно-ориентированную систему.

Вот тогда действительно, оказывается, что чтобы понять, что загружать B, нужно сначала загрузить A. Ссылки-с.
Вблизи всё выглядит правильно: как же еще обходить список, кроме как при помощи LL? Чуть подальше всё выглядит по-другому: список — противоестественная конструкция для БД, именно потому, что невозможно заранее сказать, что загружать. Приложение должно быть спроектировано так, чтобы заранее можно было сказать, что загружать. Это инженерная задача.

C>В том-то и дело, что справляются хуже. На практике нужна смесь реляционного и объектного подхода.

А что именно от объектного подхода нам нужно? Не могут ли это обеспечить lightwaight ORM?

C>Все мои приложения под этот класс подходят. Обычно на ORM прекрасно пишется 95% кода, с остальными 5% в виде ручного SQL.

А мы в общаге 95% еды ели алюминиевыми ложками. Потому что вилка была всего одна
На что похожи все предметы, когда у тебя молоток?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Взаимодействие с Базой Данных из C# по схеме MS
От: WaSh http://kxlm.blogspot.com/
Дата: 17.09.08 05:50
Оценка: :))
Вот так безобидный вопрос..... вырос в священные войны...
... << RSDN@Home 1.2.0 alpha 4 rev. 1108>>
блог http://kxlm.blogspot.com/
Re[15]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 06:32
Оценка:
Здравствуйте, IB, Вы писали:

C>>Если нужна часть — то обычно её загружают отдельно (запросом, например). Так что загрузка все коллекции — это прекрасно работающая консервативная стратегия.

IB>Ага, здесь играем, здесь не играем, а здесь я рыбу заворачивал.. =)
То есть?

C>>На практике (лично мне), например, очень часто удобно запросом выделить нужные объекты и работать с ними.

IB>Вот именно, только причем тут LL?
А потом по связям этих объектов пройтись, с использованием LL.

C>>LL работает тут как удобный "парашют" для тех случаев, когда нужно взять несколько незагруженных объектов.

IB>На практике, необходимость такого парашюта означает, что ты просто чего-то не додумал.
Да. И что из этого?

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

C>> Т.е. начинаем оптимизацию, когда она mature.

IB>Только мы premature приволокли большую пушку в виде ORM и думаем, как бы использовать все ее красивые возможности, а потом оптимизируем последствия..
ORM реально позволяет сократить затраты по времени разработки, так что всё нормально. И использовать ORM совсем несложно.

C>> Например, если нам достоверно известно, что в ходе выполнения метода понадобится подгрузить всего несколько объектов. Но невозможно заранее сказать каких.

IB>Что мешает явно подгрузить, когда станет известно?
Ну а что по-твоему делает LL?

C>>В том-то и дело, что справляются хуже.

IB>Чем?
Сложнее использовать в коде, который ориентирован на объектный стиль использования данных.

C>> На практике нужна смесь реляционного и объектного подхода.

IB>А вот здесь отлично себя показывает Linq — не linq2SQL, а просто Linq и порочая функциональщина, и ORM тут совершенно непричем, это уже не их зона ответственности.
LINQ — он для выбора данных. Ну получишь ты массив анонимных туплов. Что дальше делать с ними?

C>>Все мои приложения под этот класс подходят. Обычно на ORM прекрасно пишется 95% кода, с остальными 5% в виде ручного SQL.

IB>Ага, ты, помнится, хвастался, как пол гибернейта под свою задачу переписал.
Ну не половину, просто некоторые баги в тёмных углах там пофиксил. Оказалось быстрее, чем переписывать всё с нуля.
Sapienti sat!
Re[15]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 06:52
Оценка: +1 -1
Здравствуйте, Sinclair, Вы писали:

C>>Опять абсолюты. На практике (лично мне), например, очень часто удобно запросом выделить нужные объекты и работать с ними. LL работает тут как удобный "парашют" для тех случаев, когда нужно взять несколько незагруженных объектов.

S>Это очень дорогой парашют. Лично мне он больше напоминает мышеловку.
Ты жалуешься на то, что .NET в обязательном порядке проверяет индексы массивов? А ведь то же самое, по сути — замедление в некоторых случаях может быть очень заметным по сравнению с нативным кодом.

S>Что значит "когда она mature"? Я вижу два варианта трактовки "LL optimization maturity":

S>1. Мы наконец поняли, какие объекты мы трогаем в рамках часто используемых use-case, и специальными хинтами вынуждаем ORM выполнить раннюю загрузку
Да, именно этот сценарий и есть mature. Вдобавок, тут надо ещё добавить, что нас интересуют не все наиболее часто используемые use-case'ы, а только самые тормозящие.

Их обычно совсем немного, это скорее всего будут какие-то выборки, работающие с большим числом элементов. А методы типа add_order/remove_order/assign_product_to_order будут прекрасно работать что с LL, что без него. Так как разница между одной SQL-командой или, скажем, тремя — ничтожна, если они вызываются всего несколько раз в секунду.

S>В итоге, мы имеем отсутствие LL на основных путях работы системы (и наш код эквивалентен загрузке датасетов с точностью до синтаксиса), и всё еще неприлично тормозную реализацию редких юз-кейзов.

На нагруженных путях ещё может быть и оптимизированный ручной SQL и специальная обработка запросов. На то они и нагруженные пути.

Зато при этом за счёт того, что в редких use-case'ах не надо заниматься premature-оптимизацией, имеем выигрыш в общем времени разработки.

C>>Кстати, возможны и ситуации, когда LL экономит время. Например, если нам достоверно известно, что в ходе выполнения метода понадобится подгрузить всего несколько объектов. Но невозможно заранее сказать каких.

S>Не понял. Где экономия-то? Если нам невозможно сказать заранее, каких объектов, то мы просто будем вынуждены их загружать.
Ну да, в виде отдельных запросов, с поведением изоморфным LL.

S>А вообще, ситуация "невозможности заранее" в некотором смысле искусственная. Это опять про девиации сознания, вызванные инструментом.

Необязательно. Например, у меня есть условия, которые в SQL записываются в виде килобайтного кода.

S>Поясню тезис: когда приложение проектирует программист-реляционщик, он всё время мыслит в терминах РСУБД и запросов. Когда ему нужно отбирать объекты по сложному критерию, он сразу думает о дополнительном поле (возможно, вычисляемом). Если ему нужно выводить произвольно отсортированный список, он придумает дополнительное поле "порядок для вывода".

И это очень быстро превращает схему БД в некий аналог Ктулху.

S>Вблизи всё выглядит правильно: как же еще обходить список, кроме как при помощи LL? Чуть подальше всё выглядит по-другому: список — противоестественная конструкция для БД, именно потому, что невозможно заранее сказать, что загружать. Приложение должно быть спроектировано так, чтобы заранее можно было сказать, что загружать. Это инженерная задача.

Список — это вообще последнее дело. Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

C>>В том-то и дело, что справляются хуже. На практике нужна смесь реляционного и объектного подхода.

S>А что именно от объектного подхода нам нужно? Не могут ли это обеспечить lightwaight ORM?
От объектного подхода нам нужны графы объектов, которые ведут себя как графы объектов.

Lightweight ORM я лично пробовал, и может кому-то и нравится возиться с ними, оптимизируя каждый уголок. Но мне они просто не приносили существенной выгоды при увеличении объёмов ручной работы (читать: "мест для ошибок").

Идеально подошли бы гибридные OODB+RDB, но нет их сейчас нормально на рынке, что тут сделать.

C>>Все мои приложения под этот класс подходят. Обычно на ORM прекрасно пишется 95% кода, с остальными 5% в виде ручного SQL.

S>А мы в общаге 95% еды ели алюминиевыми ложками. Потому что вилка была всего одна
Я вот 90% еды сейчас палочками ем. Это удобнее, чем вилка!

S>На что похожи все предметы, когда у тебя молоток?

Т.е. lightweight ORM?
Sapienti sat!
Re[12]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 06:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Не приведёт. Стандартно для LL — загружать сразу всю коллекцию Items. Так что такой код будет работать вполне прилично.

S>Ты, наверное, не заметил, что Items — это OrderItems. Каждая, естественно, указывает на отдельную StockItem. И вот тут и начинаются чудеса в решете.
Действительно, не заметил.

Тогда да, стоит загрузить эти объекты сразу.

C>>У меня вообще ощущение, что если возникают проблемы с LL, то стоит посмотреть не делаем ли мы в коде слишком много лишних действий.

S>Всё как раз наоборот: чтобы с LL проблем не было, придется делать лишние действия.
Уже ответил.
Sapienti sat!
Re[16]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 07:47
Оценка: 26 (1) +3 -1
Здравствуйте, Cyberax, Вы писали:
C>Ты жалуешься на то, что .NET в обязательном порядке проверяет индексы массивов?
Нет, не жалуюсь. И вот почему:
1. В большинстве случаев обработка элемента стоит значительно дороже, чем проверка индекса при его получении. Это означает, что улучшить производительность путем отказа от проверки можно только незначительно.
2. В большинстве их тех случаев, когда обработка элемента очень дешевая по сравнению с его получением, джит устраняет лишние проверки
3. В остальных случаях я вынужден смириться с тем, что мне навязывают гарантию defined behavior ценой снижения производительности
C>А ведь то же самое, по сути — замедление в некоторых случаях может быть очень заметным по сравнению с нативным кодом.
Ну, во-первых, настолько заметного замедления на индексах получить вообще невозможно. Напомню, что мы говорим о двух-трех десятичных порядках разницы.
Во-вторых, проверка индексов дает мне функциональное преимущество. Это понятно? А LL дает мне всего лишь повязку на глаза, чтобы я не видел, когда данные будут загружены.

S>>1. Мы наконец поняли, какие объекты мы трогаем в рамках часто используемых use-case, и специальными хинтами вынуждаем ORM выполнить раннюю загрузку

C>Да, именно этот сценарий и есть mature.
Отлично. А что нам мешало понять сразу, какие объекты нам нужны? Резервирование товара — не rocket science; всё равно мы придем к тому же самому, только в профиль.

C>Вдобавок, тут надо ещё добавить, что нас интересуют не все наиболее часто используемые use-case'ы, а только самые тормозящие.

Это ты как раз перешел к п.2 моего ответа.

C>Их обычно совсем немного, это скорее всего будут какие-то выборки, работающие с большим числом элементов. А методы типа add_order/remove_order/assign_product_to_order будут прекрасно работать что с LL, что без него.

В принципе да; атомарные изменения по ID объекта работают приемлемо, поскольку LL фактически делает ту же самую работу, что и eager load.

C>Так как разница между одной SQL-командой или, скажем, тремя — ничтожна, если они вызываются всего несколько раз в секунду.


C>На нагруженных путях ещё может быть и оптимизированный ручной SQL и специальная обработка запросов. На то они и нагруженные пути.

Непонятно, почему не начать с того, чтобы честно разделить фазу получения данных и фазу их обработки, вместо того, чтобы убеждаться, что система не работает.
C>Зато при этом за счёт того, что в редких use-case'ах не надо заниматься premature-оптимизацией, имеем выигрыш в общем времени разработки.
Непонятно, что тут есть оптимизация. Я же не предлагаю сразу начинать с оптимизированного вручную SQL. Я просто предлагаю писать код в другом стиле.
Объем кода получится тот же самый; поэтому неясно, за счет чего мы проиграем во времени разработки.

S>>Не понял. Где экономия-то? Если нам невозможно сказать заранее, каких объектов, то мы просто будем вынуждены их загружать.

C>Ну да, в виде отдельных запросов, с поведением изоморфным LL.

C>Необязательно. Например, у меня есть условия, которые в SQL записываются в виде килобайтного кода.

Вот это интересно. Расскажи — попробуем отделить девиации от сознания.

C>И это очень быстро превращает схему БД в некий аналог Ктулху.

Правда что ли? А введение "недозаполненных" прокси-классов для оптимизации выборок в ORM не превращает схему маппинга в Ктулху?

C>Список — это вообще последнее дело. Чаще всего для LL характерен такой код "someStudent.getParentGroup().getGroupPrefect().addToAssignments(...)".

Тоже хорошо.

C>От объектного подхода нам нужны графы объектов, которые ведут себя как графы объектов.

Вот тут опять непонятно. Лично меня всегда напрягало, что для разных юзкейзов нужны разные графы объектов. Вот в РСУБД с этим все очень хорошо: кодд выполнил домашнее задание по реляционной алгебре. Я конструирую нужную реляцию, а сервер обеспечивает мне ее выполнение. Я никак не ограничен набором хранимых таблиц в своих манипуляциях. А ОРМ предполагает, что я придумаю некий единый граф объектов, и всю жизнь приложения буду с ним работать. Я не могу получить напрямую граф из префектов и студентов, я вынужден тащить объекты групп, которые их объединяют. И навигироваться вдоль этого графа. А если мне не нравятся длинные пути, то мне придется вручную прокладывать шорткаты и следить за их обновлением.

C>Lightweight ORM я лично пробовал, и может кому-то и нравится возиться с ними, оптимизируя каждый уголок.

Непонятно, что такое "оптимизировать каждый уголок"
C> Но мне они просто не приносили существенной выгоды при увеличении объёмов ручной работы (читать: "мест для ошибок").
Непонятно, откуда увеличение объемов ручной работы. Это ты про написание самодельного кэша и LL?

C>Идеально подошли бы гибридные OODB+RDB, но нет их сейчас нормально на рынке, что тут сделать.

Ты знаешь, я даже в ООДБ как-то сомневаюсь. Точнее, я пока вижу мало способов существенно улучшить нынешнюю ситуацию путем внедрения ООДБ. Так, чтобы это не превратилось в плохую копию РДБ. Я бы понял, если бы удалось получить нормальную компонентную модель.
C>Я вот 90% еды сейчас палочками ем. Это удобнее, чем вилка!
Открой для себя прелесть борща
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Взаимодействие с Базой Данных из C# по схеме MS
От: Cyberax Марс  
Дата: 17.09.08 08:12
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

S>Во-вторых, проверка индексов дает мне функциональное преимущество. Это понятно? А LL дает мне всего лишь повязку на глаза, чтобы я не видел, когда данные будут загружены.

LL тоже даёт тебе функциональное преимущество — возможность писать persistent-unaware код.

C>>Да, именно этот сценарий и есть mature.

S>Отлично. А что нам мешало понять сразу, какие объекты нам нужны? Резервирование товара — не rocket science; всё равно мы придем к тому же самому, только в профиль.
Может быть, логика в процессе разработки поменялась, или ещё что-нибудь. Не все же делают странички, просто показывающие результат одного запроса.

C>>Их обычно совсем немного, это скорее всего будут какие-то выборки, работающие с большим числом элементов. А методы типа add_order/remove_order/assign_product_to_order будут прекрасно работать что с LL, что без него.

S>В принципе да; атомарные изменения по ID объекта работают приемлемо, поскольку LL фактически делает ту же самую работу, что и eager load.
Именно. Причём с меньшим числом ручных теложвижений.

C>>На нагруженных путях ещё может быть и оптимизированный ручной SQL и специальная обработка запросов. На то они и нагруженные пути.

S>Непонятно, почему не начать с того, чтобы честно разделить фазу получения данных и фазу их обработки, вместо того, чтобы убеждаться, что система не работает.
Получение данных тоже разное бывает.

S>Непонятно, что тут есть оптимизация. Я же не предлагаю сразу начинать с оптимизированного вручную SQL. Я просто предлагаю писать код в другом стиле.

S>Объем кода получится тот же самый; поэтому неясно, за счет чего мы проиграем во времени разработки.
Объём кода получится НЕ тот же самый. Хотя бы из-за того, что с LL можно оставить некоторые неявные зависимости на совести самой ORM, и не прописывать их явно в запросах.

Например, у меня самое противное — часто логику придётся дублировать в SQL и в основном коде. Для меня достаточно частая ситуация — есть некая state-машина и объекты с состоянием, и нужно выбрать все объекты, для которых возможен переход в состояние "C" с учётом правил доступа текущего пользователя. На SQL это сделать проблематично, так как переходы между состояниями зависят от многих факторов.

Моё решение — берём все объекты с помощью грубого фильтра (наличие цепочки переходов до состояния "C", не считая ACL). А потом эти объекты отдельно уже профильтровать тонким фильтром. Так вот этот тонкий фильтр написан так, что он не знает что-либо о персистентности объектов, так что он может использоваться и в контексте неперсистентных графов объектов в памяти.

Конечно, можно было бы написать тонкий фильтр в виде хранимки, но тогда пришлось бы поддерживать два варианта кода — в этой хранимке, и на Java.

C>>Необязательно. Например, у меня есть условия, которые в SQL записываются в виде килобайтного кода.

S>Вот это интересно. Расскажи — попробуем отделить девиации от сознания.
См. выше.

C>>И это очень быстро превращает схему БД в некий аналог Ктулху.

S>Правда что ли? А введение "недозаполненных" прокси-классов для оптимизации выборок в ORM не превращает схему маппинга в Ктулху?
Нет. С чего бы? Lazy loading не влияет на схему саму по себе.

C>>От объектного подхода нам нужны графы объектов, которые ведут себя как графы объектов.

S>Вот тут опять непонятно. Лично меня всегда напрягало, что для разных юзкейзов нужны разные графы объектов. Вот в РСУБД с этим все очень хорошо: кодд выполнил домашнее задание по реляционной алгебре. Я конструирую нужную реляцию, а сервер обеспечивает мне ее выполнение.
Ты забыл только упомянуть, что классический SQL — он не Turing-complete. ОЧЕНЬ не Turing-complete.

S>Я никак не ограничен набором хранимых таблиц в своих манипуляциях. А ОРМ предполагает, что я придумаю некий единый граф объектов, и всю жизнь приложения буду с ним работать. Я не могу получить напрямую граф из префектов и студентов, я вынужден тащить объекты групп, которые их объединяют. И навигироваться вдоль этого графа. А если мне не нравятся длинные пути, то мне придется вручную прокладывать шорткаты и следить за их обновлением.

Если не нравятся длинные пути — просто переходишь на реляционный стиль. В этом и сила ORM.

C>>Lightweight ORM я лично пробовал, и может кому-то и нравится возиться с ними, оптимизируя каждый уголок.

S>Непонятно, что такое "оптимизировать каждый уголок"
Отдельно заниматься mapping'ом результатов каждого запроса или загрузкой всего необходимого.

C>> Но мне они просто не приносили существенной выгоды при увеличении объёмов ручной работы (читать: "мест для ошибок").

S>Непонятно, откуда увеличение объемов ручной работы. Это ты про написание самодельного кэша и LL?
Про бОльшее количество деталей, за которыми надо следить.

C>>Идеально подошли бы гибридные OODB+RDB, но нет их сейчас нормально на рынке, что тут сделать.

S>Ты знаешь, я даже в ООДБ как-то сомневаюсь. Точнее, я пока вижу мало способов существенно улучшить нынешнюю ситуацию путем внедрения ООДБ. Так, чтобы это не превратилось в плохую копию РДБ. Я бы понял, если бы удалось получить нормальную компонентную модель.
Часто проблема Lazy Loading'а замечательно решается применением "грубой силы" — кэшем объектов в памяти. Чем-то напоминает ситуацию в процессоростроении.

C>>Я вот 90% еды сейчас палочками ем. Это удобнее, чем вилка!

S>Открой для себя прелесть борща
А это как раз почти все остальные 10% (очень люблю окрошку)
Sapienti sat!
Re[18]: Взаимодействие с Базой Данных из C# по схеме MS
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 17.09.08 08:29
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>LL тоже даёт тебе функциональное преимущество — возможность писать persistent-unaware код.


"persistent-unaware код" может и хорошо, а вот попытка проигнорировать реляционность нижележащих данных — это значит добровольно отказаться от тех возможностей, которые РСУБД предлагает. А это плохо, и не ясно зачем тогда РСУБД вообще.

И, кстати, не знаю как NHibernate, но сам Hibernate не позволяет писать persistent-unaware код. Для меня в нём остался один бенефит — поддержка разных диалектов SQL и мне зачастую удобнее написать HQL чем эквивалентный SQL.
http://www.smalltalk.ru << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[18]: Взаимодействие с Базой Данных из C# по схеме MS
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.09.08 08:56
Оценка: +2 -1
Здравствуйте, Cyberax, Вы писали:

C>LL тоже даёт тебе функциональное преимущество — возможность писать persistent-unaware код.

Это преимущества совершенно разного рода. Контроль размеров спасает меня от ошибки.
От какой ошибки спасает меня возможность писать persistent-unaware код?
Я в очередной раз говорю о том, что абстракция LL — leaky. Не надо ее сравнивать с


C>Может быть, логика в процессе разработки поменялась, или ещё что-нибудь. Не все же делают странички, просто показывающие результат одного запроса.

Ну поменялась — мы начали загружать другие данные. В чем проблема?

C>Именно. Причём с меньшим числом ручных теложвижений.

Непонятно про меньше телодвижений.

C>Получение данных тоже разное бывает.

И?

C>Объём кода получится НЕ тот же самый. Хотя бы из-за того, что с LL можно оставить некоторые неявные зависимости на совести самой ORM, и не прописывать их явно в запросах.


C>Моё решение — берём все объекты с помощью грубого фильтра (наличие цепочки переходов до состояния "C", не считая ACL). А потом эти объекты отдельно уже профильтровать тонким фильтром. Так вот этот тонкий фильтр написан так, что он не знает что-либо о персистентности объектов, так что он может использоваться и в контексте неперсистентных графов объектов в памяти.

А по факту он используется для "неперсистентных графов"?
C>Конечно, можно было бы написать тонкий фильтр в виде хранимки, но тогда пришлось бы поддерживать два варианта кода — в этой хранимке, и на Java.
Нет, я не предлагаю опускать такую логику в СУБД. Я всего лишь не понимаю, какое место здесь занимает Lazy Load.

S>>Правда что ли? А введение "недозаполненных" прокси-классов для оптимизации выборок в ORM не превращает схему маппинга в Ктулху?

C>Нет. С чего бы? Lazy loading не влияет на схему саму по себе.
На первом этапе — нет. На втором оказывается, что поднимать StoreItem со всеми его потрохами только для того, чтобы показать его Name в составе Order Item — слишом дорого. В итоге делают двухуровневый прокси: StoreItem режут на StoreItemName и StoreItemFull. И всё это потому, что полноценная ORM предлагает жесткую схему объектов.

C>>>От объектного подхода нам нужны графы объектов, которые ведут себя как графы объектов.

S>>Вот тут опять непонятно. Лично меня всегда напрягало, что для разных юзкейзов нужны разные графы объектов. Вот в РСУБД с этим все очень хорошо: кодд выполнил домашнее задание по реляционной алгебре. Я конструирую нужную реляцию, а сервер обеспечивает мне ее выполнение.
C>Ты забыл только упомянуть, что классический SQL — он не Turing-complete. ОЧЕНЬ не Turing-complete.
Классический SQL — вообще в некотором роде фикция, т.к. он опирается на скалярные функции, набор которых — implementation-specific. А вообще, вроде бы должен быть turing-complete. Ведь достаточно иметь ноль, инкремент, и выбор N-го аргумента

C>Если не нравятся длинные пути — просто переходишь на реляционный стиль. В этом и сила ORM.

Ну-ну. И как этот реляционный стиль дружит с транзакциями и кэшем?

C>Отдельно заниматься mapping'ом результатов каждого запроса или загрузкой всего необходимого.

О да, это ж прямо ужас как приходится напрягаться, чтобы отмапить
from OrderItem i in Connection.OrderItems 
    join StoreItem si on i.StoreItemID equals si.ID
    select si.Name, i.Quantity

Прямо не знаю, сколько нужно ручной работы .
В BLToolkit, конечно, есть где разогнаться. Там придется для OrderLine писать класс. Зато не нужен класс для OrderItem, если он не используется.
C>Про бОльшее количество деталей, за которыми надо следить.
Странно. Деталей меньше в LWORM, а следить приходится больше .
C>Часто проблема Lazy Loading'а замечательно решается применением "грубой силы" — кэшем объектов в памяти. Чем-то напоминает ситуацию в процессоростроении.
Это всё обсуждалось позавчера. Извини, у меня уже терпения не хватает, чтобы объяснять каждому из вас, что я думаю про решения созданных самими же себе проблем. Потому что дальше мы будем обсуждать, как замечательно проблемы когерентности распухшего кэша решаются при помощи очередной "грубой силы".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Взаимодействие с Базой Данных из C# по схеме MS
От: Аноним  
Дата: 17.09.08 09:02
Оценка: +3
Здравствуйте, WaSh, Вы писали:

WS>Вот так безобидный вопрос..... вырос в священные войны...


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

поэтому продолжайте господа, вас приятно слушать!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.