Re[47]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 19.04.15 22:11
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

EP>>Если для mapping'а генерируется байткод (который может быть настолько быстрым, насколько позволяет платформа) и используется скомпилированный запрос — то откуда вообще взяться overhead'у?

НС>Построить запрос это дорого, в некоторых провайдерах — очень дорого. linq2db поэтому построение запроса кеширует. К сожалению, компилятор шарпа генерирует код, который строит дерево при каждом исполнении метода, т.е. дерево каждый раз разное. Из-за этого, чтобы сравнить запросы, приходится обходить это дерево и вычислять хеш. Это тоже довольно быстро, но уже не мгновенно.

Это понятно, но если использовать Compiled Query, то есть без обхода дерева — то получается что совсем не будет overhead'а? Здорово

EP>>Этот AST по идее должен лежать в памяти достаточно компактно, и соответственно должен обходится быстро.

НС>Так и есть.
EP>>, то можно попробовать сделать свой обход через unsafe Но нужно знать внутреннюю структуру, либо тогда делать reverse engineering
НС>unsafe не спасет. Единственное в чем он дает существенный выигрышь на практике — отключение проверок границ массивов. Но в Expression Tree массивов не сказать чтобы много.

Там наверняка какой-нибудь visitor на виртуальных функциях, и скорей всего обход узлов в памяти не последовательный, что медленно.
Если сделать допущение, что у одного и того же запроса узлы в памяти располагаются последовательно, то можно обходить узлы по порядку — как они лежат в памяти. Плюс надо будет "нормализировать" указатели-дуги, чтобы они не зависели от начального адреса. Плюс отказ от виртуальных функций в пользу хардкорного инлайнинга и jump table. Думаю всё это даст прирост скорости в несколько раз, а то и на порядок (порядки — если супер-оптимистично).
Но это конечно жуткий low-level hack, требующий кучи тестов и version-specific кода.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.