Re[64]: Тормознутость и кривость linq
От: alex_public  
Дата: 30.04.16 22:26
Оценка:
Здравствуйте, IT, Вы писали:

IT>Что касается производительности linq2db, то "ха-ха" здесь не уместно. Производительности всегда уделялось самое пристальное внимание в том числе с помощью тяжёлой артиллерии типа Red-Gate ANTS Performance Profiler‎. При этом внимательно изучался код того же dapper, linq2sql, EF, были бессовестно украдены некоторые идеи, правда не касающиеся производительности. Выше упомянутый OrmBattle тоже сподвиг на работу над производительностью. В linq2db вошло лучшее из bltoolkit и RFD, а это как минимум 13 лет опыта разработки и использования подобных технологий.

IT>Но главное — первыми пользователями linq2db, bltoolkit и RFD всегдя являлись сами разработчики этих библиотек. А халтурить для себя как-то непонятно зачем

1. Вообще то я как раз везде писал про linq2db как про "лучшее решение в данной области".
2. Обсуждается здесь даже не конкретная ORM, а задание запросов с помощью Linq. У того же linq2db есть оба режима.
3. Так вот даже "самое лучшее решение" даёт с Linq существенные накладные расходы. А про цифры не самого лучшего (но самого популярного) решения вообще говорить страшно. )))
Re[70]: Тормознутость и кривость linq
От: alex_public  
Дата: 30.04.16 22:34
Оценка:
Здравствуйте, IT, Вы писали:

_>>Не надо мне какие-то исходники показывать. Покажи просто один linq запрос и генерируемые из него оптимизированные sql строки под разные СУБД. Всё. Такая простая вещь будет 100% доказательством.

IT>Мне на слово поверишь как разработчику?
IT>Оптимизируются. В несколько подходов. От обработки Expression Tree, до генерации SQL для различных дата провайдеров.

Так а пример то можно? ) Чтобы разница была не в соответствие синтаксису конкретной СУБД, а именно в оптимзиации.

IT>Главная проблема не в оптимизации как таковой, а в наличиствующих инструментах. Дайте паттерн матчинг в C# и отжать всё лишнее из генерируемого SQL вообще будет не проблема.


Ты этим собираешься заниматься в рантайме? )
Re[96]: Тормознутость и кривость linq
От: alex_public  
Дата: 30.04.16 22:36
Оценка:
Здравствуйте, ·, Вы писали:

TK>>>Дерево в Linq анализируется обычно через ExpressionVisitor. С каких это пор для обхода дерева нужна рефлексия?

_>>Отвечу так http://stackoverflow.com/questions/5396290/does-entity-framework-use-reflection-and-hurt-performance просто чтобы не тратить самому время на поиск доказательств (без этого в данной темке уже не верят) в документации и исходниках. )
·>Это вообще-то об EF, а значит "LINQ to Entities".. Мы вообще-то о другом.

И о чём же другом? )
Re[97]: Тормознутость и кривость linq
От: · Великобритания  
Дата: 01.05.16 01:18
Оценка:
Здравствуйте, alex_public, Вы писали:

_>>>Отвечу так http://stackoverflow.com/questions/5396290/does-entity-framework-use-reflection-and-hurt-performance просто чтобы не тратить самому время на поиск доказательств (без этого в данной темке уже не верят) в документации и исходниках. )

_>·>Это вообще-то об EF, а значит "LINQ to Entities".. Мы вообще-то о другом.

_>И о чём же другом? )

О linq. В linq рефлексии — нет, как оказалось. Она есть в EF, да и то в start-up time, т.е. разогретый код рефлексировать не будет.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[71]: Тормознутость и кривость linq
От: IT Россия linq2db.com
Дата: 01.05.16 01:54
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Так а пример то можно? ) Чтобы разница была не в соответствие синтаксису конкретной СУБД, а именно в оптимзиации.


Я не совсем понимаю разницу, да и самой постановки задачи тоже. Есть разные СУБД, для них делается попытка построить наиболее оптимальный SQL, в том числе для разных версий СУБД. Возьмём, напрмер, пейджинг. Есть такой тест:

[Test, DataContextSource]
public void SkipTake1(string context)
{
    using (var db = GetDataContext(context))
    {
        var expected =    Child.OrderByDescending(c => c.ChildID).Skip(2).Take(5);
        var result   = db.Child.OrderByDescending(c => c.ChildID).Skip(2).Take(5);
        Assert.IsTrue(result.ToList().SequenceEqual(expected));
    }
}


Генерируемый SQL для разных провайдеров:

-- Access
-- Skip делается в вызывающим кодом.
SELECT TOP 7
    [t1].[ParentID],
    [t1].[ChildID]
FROM
    [Child] [t1]
ORDER BY
    [t1].[ChildID] DESC


-- DB2.LUW
-- Версию для z/OS привести не могу, т.к. пока не обзавёлся дома мэйнфремом.
SELECT *
FROM
(
    SELECT
        t.*,
        ROW_NUMBER() OVER() as rn
    FROM
    (
        SELECT
            "t1"."ParentID",
            "t1"."ChildID"
        FROM
            "Child" "t1"
        ORDER BY
            "t1"."ChildID" DESC
    ) t
) t2
WHERE
    t2.rn BETWEEN 3 AND 7


-- Firebird
SELECT FIRST 5 SKIP 2
    t1.ParentID,
    t1.ChildID
FROM
    Child t1
ORDER BY
    t1.ChildID DESC


-- Informix
SELECT SKIP 2 FIRST 5
    t1.ParentID,
    t1.ChildID
FROM
    Child t1
ORDER BY
    t1.ChildID DESC


-- MySql
SELECT
    `t1`.`ParentID`,
    `t1`.`ChildID`
FROM
    `Child` `t1`
ORDER BY
    `t1`.`ChildID` DESC
LIMIT 2,5


-- Oracle.Managed Oracle
SELECT t2.*
FROM
(
    SELECT t.*, ROWNUM as rn
    FROM
    (
        SELECT
            t1.ParentID,
            t1.ChildID
        FROM
            Child t1
        ORDER BY
            t1.ChildID DESC
    ) t
    WHERE
        ROWNUM <= 7
) t2
WHERE
    t2.rn > 2


-- PostgreSQL
SELECT
    t1."ParentID",
    t1."ChildID"
FROM
    "Child" t1
ORDER BY
    t1."ChildID" DESC
LIMIT 5 OFFSET 2 


-- SQLite
SELECT
    [t1].[ParentID],
    [t1].[ChildID]
FROM
    [Child] [t1]
ORDER BY
    [t1].[ChildID] DESC
LIMIT 5 OFFSET 2


-- SqlCe
SELECT
    [t1].[ParentID],
    [t1].[ChildID]
FROM
    [Child] [t1]
ORDER BY
    [t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY 


-- SqlServer.2005б SqlServer.2008
SELECT *
FROM
(
    SELECT
        t.*,
        ROW_NUMBER() OVER
        (
            ORDER BY
                oby DESC
        ) as rn
    FROM
    (
        SELECT
            [t1].[ParentID],
            [t1].[ChildID],
            [t1].[ChildID] as [oby]
        FROM
            [Child] [t1]
    ) t
) t2
WHERE
    t2.rn BETWEEN 3 AND 7


-- SqlServer.2012б SqlServer.2014
SELECT
    [t1].[ParentID],
    [t1].[ChildID]
FROM
    [Child] [t1]
ORDER BY
    [t1].[ChildID] DESC
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY 


-- Sybase
-- Skip тоже делается на клиенте. Криворукие китайцы никак не сделают нормальную поддержку для пейджинга.
SELECT TOP 7
    [t1].[ParentID],
    [t1].[ChildID]
FROM
    [Child] [t1]
ORDER BY
    [t1].[ChildID] DESC


Версии для SAP Hana не привожу, т.к. всё никак не могу настроить доступ. К SqlServer 2000 тоже, т.к. оно стоит на отдельной VM, которую лень загружать. Но там, что-то вроде аналога Sybase.

IT>>Главная проблема не в оптимизации как таковой, а в наличиствующих инструментах. Дайте паттерн матчинг в C# и отжать всё лишнее из генерируемого SQL вообще будет не проблема.


_>Ты этим собираешься заниматься в рантайме? )


Да. Есть такое волшебное слово — кеширование, которое позволяет забить на проблемы производительности.
Если нам не помогут, то мы тоже никого не пощадим.
Re[73]: Тормознутость и кривость linq
От: IT Россия linq2db.com
Дата: 01.05.16 02:40
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Я некорректно выразился. Нужно что бы ты подсказал на счет разницы между Linq2db vs Linq2db-raw-SQL. Она довольно большая, судя по тесту, 10-100%. Нужна структура расходов вот этой разницы.


Основные расходы на Raw SQL — это генерация маррера из IDataReader в целевой объект. Но это дело кешируется, поэтому со второго раза абсолютно не затратно.

С linq всё гораздо сложнее. Запросы тоже кешируются, но т.к. у ExpressionTree не может быть хеш функции по определению, то первым делом Expression сравнивается последовательно с закешированными запросами. Т.к. в приложении количество разных запросов может исчисляться сотнями, то первый уровень кеша — это тип возвращаемого запроса. В целом такой подход неплохо работает. Была идея использовать для первого уровня кеша Stack Trace, но оказалось, что это штука просто нереально тормозная и была предана анафеме.

Думаю на том как происходит обработка дерева останваливаться не стоит, т.к. этот процесс всё равно кешируется. Важнее другое. В отличии от linq2sql linq2db генерирует SQL не напрямую из ExpressionTree, а через промежутоный SQL AST. На самом деле то, что linq2sql делает на одном проходе по дереву вызывает уважение. Честное слово, снимаю шляпу. Хотя это и не удивительно, т.к. его писала команда разработчиков C#. Видимо в этом и его главная проблема. Кроме них развивать проект никто в MS не смог, а у них было чем заняться и без linq2sql. Впрочем это всего лишь мои предположения.

Далее. После создания SQL AST есть два варианта: закешировать сгенерированный SQL и перестраивать SQL под каждый новый запрос.

Последее делать необходимо, например, в слуве ...Where(t => t.Field == abc), т.к. если t.Filed is nullable, то abc может оказаться NULL и нужно вместо t.Field = @abc генерировать t.Filed IS NULL.

После этого остаётся сгенерировать маппер в целевой объект. На этом всё.
Если нам не помогут, то мы тоже никого не пощадим.
Re[98]: Тормознутость и кривость linq
От: alex_public  
Дата: 01.05.16 02:50
Оценка:
Здравствуйте, ·, Вы писали:

_>>Ты похоже не осознаёшь масштабы временных задержек, о которых говоришь. Даже самый тормознутые мейнстрим языки (Python и PHP) выполнят указанный пример на порядки быстрее времени обработки запроса в СУБД. Т.е. разница между языками вообще тут не принципиальна.

·>Нет, я свожу к абсурду твою точку зрения. Хотя ты опять сам справляешься лучше. Вот сейчас сказал, что PHP тормоза не оказывают ощутимое влияние в случае работы с СУБД, а linq рефлексия (которой как выяснилось нет) вдруг стала источником тормозов?

Да, всё так и есть. А в чём ты видишь тут абсурд? ) Или быть может ты хочешь сказать, что рефлексия в .net очень шустрая? ))) Но в любом случае, даже если бы была шустрая, то всё равно ничего не изменилось, т.к. это код работает в дополнение, а не вместо базового.

_>>Ты похоже путаешь просто linq и linq2database. В первом случае у нас действительно исполняется само выражение. А во втором случае совсем другая схема — выражение используется по сути как набор данных (дерево) из которых генерируется sql текст.

·>Ок. Допустим. И причём тут рефлексия?
·>И чем принципиально этот набор данных отличается от такого if(categoryName) q.where.add(Category.name.like(*categoryName+"%"))

Вот недаром я начинал с примеров на чистом sql. Поняв их можно было легко понять остальное, но ты похоже не осилил этого.

Тот самый код с if'ми, склейкой строк и т.п. существует во всех трёх случаях (голые строки, sqlpp, linq). Собственно иначе и не могло быть. Только выглядит это в каждом случае по разному.

В первом случае у тебя просто тупо код if(cond) q+="table.field>"+to_string(cond), который прямо и выполняется.

Во втором случае у тебя нечто более хитрое, которое в итоге сводится к чему-то вроде if(cond) нечто_превращаемое_компилятором_в_код(q+="table"+"."+"field"+">"+to_string(cond)), что в итоговом бинарнике не сильно отличается от первого случая. )

В третьем случае у тебя в начале код вида if(cond) добавить_в_дерево_выражение(field>cond), а потом где-то в другом месте находится универсальный код обхода дерева (очень тормознутый кстати, причём не по вине разработчиков ORM, а из-за устройства самого .net), в котором будет в том числе и что-то вроде if(знак_больше) q+="table"+"."+to_string(первый_аргумент_знака_больше)+">"+to_string(второй_аргумент_знака_больше). Это естественно так, на пальцах. Реальное устройство можешь глянуть например тут http://stackoverflow.com/questions/7731905/how-to-convert-an-expression-tree-to-a-partial-sql-query.

Теперь понятна разница? )
Re[96]: Тормознутость и кривость linq
От: alex_public  
Дата: 01.05.16 03:53
Оценка:
Здравствуйте, ·, Вы писали:

·>Да и вообще. Ты уже заметил разницу? Вместо трёх тривиальных if тебе пришлось забабахать ещё один магический новый (кстати надо было два, т.к. у меня было Category.Group.Name — т.е. ещё один join). А ведь мы ещё проекции не добавили, а ещё сортировки есть... Сложность кода растёт экспоненциально.


Откуда экспоненциально? ) Как раз чётко линейно по количеству фильтров и таблиц.
Re[98]: Тормознутость и кривость linq
От: alex_public  
Дата: 01.05.16 04:03
Оценка:
Здравствуйте, ·, Вы писали:

_>>·>Это вообще-то об EF, а значит "LINQ to Entities".. Мы вообще-то о другом.

_>>И о чём же другом? )
·>О linq. В linq рефлексии — нет, как оказалось. Она есть в EF, да и то в start-up time, т.е. разогретый код рефлексировать не будет.

Такие фразы надо прямо записывать. Хорошо, сформулирую по другому, для особо одарённых. ) Подскажи мне какая ORM основанная на Linq обходится без рефлексии? )

Ну и насчёт start-up time — это тоже фееричный бред. На самом деле под этим делом подразумевают банальное кэширование сгенерированных запросов. Но с этим там тоже далеко не всё так просто (см. что IT пишет).
Re[72]: Тормознутость и кривость linq
От: alex_public  
Дата: 01.05.16 04:13
Оценка:
Здравствуйте, IT, Вы писали:

_>>Так а пример то можно? ) Чтобы разница была не в соответствие синтаксису конкретной СУБД, а именно в оптимзиации.

IT>Я не совсем понимаю разницу, да и самой постановки задачи тоже. Есть разные СУБД, для них делается попытка построить наиболее оптимальный SQL, в том числе для разных версий СУБД. Возьмём, напрмер, пейджинг. Есть такой тест:

Ну так вот прямо этот пример мы тут разбирали уже. И это как раз классический пример следования особенностям синтаксиса конкретной СУБД (просто через соответствующий вызов функции провайдера). Это как бы везде такое тривиально реализуется. Мне тут обещали совсем другое, реальную умную оптимизацию. Что типа ORM будет в зависимости от вида СУБД менять join'ы на подзапросы или что-то такое, т.к. они в ней быстрее выполняются. В общем какие-то реальные оптимизации, а не следования синтаксису (собственно ты ему физически не можешь не следовать, так что это не оптимизация, а просто минимальная реализация).

IT>>>Главная проблема не в оптимизации как таковой, а в наличиствующих инструментах. Дайте паттерн матчинг в C# и отжать всё лишнее из генерируемого SQL вообще будет не проблема.

_>>Ты этим собираешься заниматься в рантайме? )
IT>Да. Есть такое волшебное слово — кеширование, которое позволяет забить на проблемы производительности.

Что-то сомнительно, сам же писал выше какие там проблемы возникают. ) Вот в предкомпилированные запросы я ещё верю, правда они не везде применимы и не так удобны.
Re[90]: Тормознутость и кривость linq
От: alex_public  
Дата: 01.05.16 04:53
Оценка:
Здравствуйте, Ikemefula, Вы писали:

_>>Имеем где-то порядка 2-12 микросекунд накладных расходов на простом запросе классического вида ради получения статически типизированного кода. Конечно не идеал, но уже вполне терпимо, а не дикие 12 миллисекунд как у твоих примеров с linq.

I> Ты прочитал данные даже не из локального файла, а из кеша операционной системы. 2-12микросекунд это чтение данных из прогретого кеша операционной системы, фактически — обращение к виртуальной памяти. База то у тебя вся в памяти, алё !
I> Отключал ты индексы или нет, значения почти не имеет, ибо ты перепахиваешь виртуальную память, но сравниваешь с чтением по сети
I>Те самые 12мс — это именно обращение и передача данных по сети. Кроме того, если ты помнишь, то там даже прямой доступ к бд давал почти те же милисекунды.
I>На С++ аналог того самого теста, скажем, через драйвер odbc, не cможет дать меньше чем милисекунды, ну никак.

Ты совсем глупый или не умеешь читать? ) И 2-12 микросекунд и 12 миллисекунд — это накладные расходы (а не суммарное время), которые в принципе никак не зависят от времени исполнения самого запроса. Хоть там будет наносекунда, хоть час. Накладные расходы у таких библиотек зависят исключительно от самого запроса и всё. Так что для приведённого в тесте запроса такие накладные расходы будут на любом, даже самом удалённом сервере. ))) Единственная разница заключается в том, что при времени исполнения запроса в час очень проблематично (хотя откуда тебе знать такое, ты же про теорию эксперимента даже не слышал) измерить накладные расходы в несколько микросекунд.

P.S. Ну и для общего образования: обращение к памяти — это наносекунды, у нас всё же не 90-ые. )))
Re[99]: Тормознутость и кривость linq
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.05.16 05:38
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Да, всё так и есть. А в чём ты видишь тут абсурд? ) Или быть может ты хочешь сказать, что рефлексия в .net очень шустрая? ))) Но в любом случае, даже если бы была шустрая, то всё равно ничего не изменилось, т.к. это код работает в дополнение, а не вместо базового.


Так ты расскажи уже, где именно узкое место — рефлексия ?

_>В третьем случае у тебя в начале код вида if(cond) добавить_в_дерево_выражение(field>cond), а потом где-то в другом месте находится универсальный код обхода дерева (очень тормознутый кстати, причём не по вине разработчиков ORM, а из-за устройства самого .net),


System.Linq.Expressions, Обход выполняется один раз, дальше — результаты кешируются.

>Реальное устройство можешь глянуть например тут http://stackoverflow.com/questions/7731905/how-to-convert-an-expression-tree-to-a-partial-sql-query.


System.Linq.Expressions, И снова ничего про рефлексию
Re[99]: Тормознутость и кривость linq
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.05.16 05:41
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Такие фразы надо прямо записывать. Хорошо, сформулирую по другому, для особо одарённых. ) Подскажи мне какая ORM основанная на Linq обходится без рефлексии? )


Никакая. Ты утверждаешь, ни много ни мало, что основное время подготовки каждого запроса есть рефлексия. В примерах что ты приводишь этого в упор не видно.
Re[73]: Тормознутость и кривость linq
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.05.16 05:47
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну так вот прямо этот пример мы тут разбирали уже. И это как раз классический пример следования особенностям синтаксиса конкретной СУБД (просто через соответствующий вызов функции провайдера). Это как бы везде такое тривиально реализуется.


Структура разная.

>Мне тут обещали совсем другое, реальную умную оптимизацию. Что типа ORM будет в зависимости от вида СУБД менять join'ы на подзапросы или что-то такое, т.к. они в ней быстрее выполняются. В общем какие-то реальные оптимизации, а не следования синтаксису (собственно ты ему физически не можешь не следовать, так что это не оптимизация, а просто минимальная реализация).


И когда тебе показали запрос, что в одной базе делает джойн, а в другой — подзапрос, ты сказал "классический пример следования особенностям синтаксиса"
Вот и получается, что хочешь увидеть в SQL чистую магию.
Re[91]: Тормознутость и кривость linq
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.05.16 05:58
Оценка: -1
Здравствуйте, alex_public, Вы писали:

_>Ты совсем глупый или не умеешь читать? ) И 2-12 микросекунд и 12 миллисекунд — это накладные расходы (а не суммарное время), которые в принципе никак не зависят от времени исполнения самого запроса. Хоть там будет наносекунда, хоть час.


Я невнимательно прочел код, у тебя в замеры в одном месте попадает tr.commit
Ты перепахиваешь память и только по этому у тебя заметны издержки. Как только начинаешь работать уже с диском, то разницы, по твоим же словам, не видно никакой.

>разница явно где-то за пределами погрешности измерения. И только введение индекса (и соответственно приведение времени запроса к смешным значениям) позволило выявить реальный размер накладных расходов данной библиотечки


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

_>P.S. Ну и для общего образования: обращение к памяти — это наносекунды, у нас всё же не 90-ые. )))


Ты всё таки не можешь удержаться, что бы не юродствовать. Типа ты не понял, что речь про _виртуальную_ _память_ и надо считать commit и дисковый io
Отредактировано 01.05.2016 12:49 Pauel . Предыдущая версия . Еще …
Отредактировано 01.05.2016 6:09 Pauel . Предыдущая версия .
Re[90]: Тормознутость и кривость linq
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.05.16 08:36
Оценка: +1
Здравствуйте, alex_public, Вы писали:

N>>Сразу дисклеймер: нет, я не поддерживаю позицию alex_public, что это всё лучше делать так вручную — хотя бы потому, что я банально ленив (той ленью, которая достоинство программиста), и в первую очередь побежал бы за готовым средством. Но и рассказ про 1024 варианта, мягко говоря, неадекватен.

_>Никто про "всё лучше делать вручную" не говорил. Речь шла про конкретный пример из данной статьи http://blog.gandjustas.ru/2014/09/23/asp.net-linq-ef-sql-server-performance/, про который я высказал оценку, что он бредовый, т.к. сравнивает исключительно хранимку vs linq.

Тогда ты очень плохо держишь исходную тему в процессе обсуждения. Потому что уже после 2-3 последующих сообщений этот исходный пример ушёл куда-то погулять, а вы радостно переключились на сложности формирования SQL.

Пример как раз достаточно разумный, если исходить из практики. Хранимка тут как раз малосущественна, такой же запрос с case внутри (неважно, явном или нет) можно было послать и напрямую с клиента (да, я видел такое в реальности). Различие именно в том, чьи затраты меньше — локального генератора (linq2db или аналога) или сервера (сможет ли сервер, например, сразу сэкономить на входе на ветке, которая при компиляции SQL запроса для него константа false).

Но дальше вы тут же растеклись на что-то совсем странное. Ты вот утверждаешь, что там внутри сплошная рефлексия, а коллеги — что там expression trees. Мне тут больше непонятно, почему рефлексия такая чудовищно дорогая — миллисекунды. Но если её нет, то и дороговизны нет, а ты ничего не мерял.

_> Потому как самая короткая запись обычного запроса является одновременно и самой оптимизированной.


Запроса SQL? Тогда это в общем случае, мягко говоря, сомнительно. И есть контрпримеры для многих баз, когда вложенный select дешевле сложного join, и другие аналогичные тонкости.

_> Автор статьи никак не мог этого осознать, пока ему не продемонстрировали этот самый запрос. Только отсюда он и появился, а не из каких-то идей писать всё руками.


И опять-таки ты плохо держишь тему.

_>P.S. Хотя в случае C# и желания максимальной производительности скорее всего только вариант голых строк и подходит.


Скорее StringBuilder

_> Но меня трудно назвать сторонником данного подхода, т.к. я собственно не сторонник самого C#. )))


Ну, зачем ты перешёл на рекламу C++ в треде дотнет против явы, отдельный вопрос.
The God is real, unless declared integer.
Re[97]: Тормознутость и кривость linq
От: · Великобритания  
Дата: 01.05.16 13:58
Оценка:
Здравствуйте, alex_public, Вы писали:

_>·>Да и вообще. Ты уже заметил разницу? Вместо трёх тривиальных if тебе пришлось забабахать ещё один магический новый (кстати надо было два, т.к. у меня было Category.Group.Name — т.е. ещё один join). А ведь мы ещё проекции не добавили, а ещё сортировки есть... Сложность кода растёт экспоненциально.

_>Откуда экспоненциально? ) Как раз чётко линейно по количеству фильтров и таблиц.
Сложность условия if зависит от того в что как пересекается.
В оригинальном коде — три тривиальных if (с одним условием), притом они могут стоять в любом порядке — достаточно написать три whitebox теста. В твоём коде с комбинациями условий, да в строго определённом порядке — хз... для безопасности я бы написал все восемь (23).
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[99]: Тормознутость и кривость linq
От: · Великобритания  
Дата: 01.05.16 14:08
Оценка:
Здравствуйте, alex_public, Вы писали:

_>>>·>Это вообще-то об EF, а значит "LINQ to Entities".. Мы вообще-то о другом.

_>>>И о чём же другом? )
_>·>О linq. В linq рефлексии — нет, как оказалось. Она есть в EF, да и то в start-up time, т.е. разогретый код рефлексировать не будет.
_>Такие фразы надо прямо записывать. Хорошо, сформулирую по другому, для особо одарённых. ) Подскажи мне какая ORM основанная на Linq обходится без рефлексии? )
Обсуждаемые нами linq2sql и вроде linq2db

_>Ну и насчёт start-up time — это тоже фееричный бред. На самом деле под этим делом подразумевают банальное кэширование сгенерированных запросов. Но с этим там тоже далеко не всё так просто (см. что IT пишет).

Почитай свою же ссылку, там написано.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[73]: Тормознутость и кривость linq
От: IT Россия linq2db.com
Дата: 01.05.16 18:15
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Ну так вот прямо этот пример мы тут разбирали уже. И это как раз классический пример следования особенностям синтаксиса конкретной СУБД (просто через соответствующий вызов функции провайдера). Это как бы везде такое тривиально реализуется.


Это смотря как на это посмотреть. Пейджинг без специфических вещей конкретной БД делается простым проматыванием ненужных данных до нужной страницы. Но это не эффективно. Поэтому для каждой БД такой запрос преобразуется в более подходящий вариант. Если заметил, то и для разных версий БД это тоже делается.

В общем, это чисто терминологический спор. Где у нас оптимизации, а где код, заточенный под конкретную СУБД.

_>Мне тут обещали совсем другое, реальную умную оптимизацию. Что типа ORM будет в зависимости от вида СУБД менять join'ы на подзапросы или что-то такое, т.к. они в ней быстрее выполняются. В общем какие-то реальные оптимизации, а не следования синтаксису (собственно ты ему физически не можешь не следовать, так что это не оптимизация, а просто минимальная реализация).


Делается. Только наоборот. Подзапросы меняются на джоины. Точнее на OUTER APPLY. SQL Server поддерживает такую фичу и для него такая замена делается.

Опять же. Я не вижу здесь вообще повода для дискуссии. Сделать оптимизации для конкретного сервера и разный код для разных СУБД — это задачи одного порядка. Там где нужно всё это делается.

IT>>Да. Есть такое волшебное слово — кеширование, которое позволяет забить на проблемы производительности.

_>Что-то сомнительно, сам же писал выше какие там проблемы возникают. ) Вот в предкомпилированные запросы я ещё верю, правда они не везде применимы и не так удобны.

Это не вопрос веры. Не надо верить / не верить. Можно всять и протестировать. Или хотя бы посмотреть результаты существующих тестов.

Тем более, что в плохом провайдере подготовка запроса это не всегда основные тормоза. Как правило тесты делаются на нешироких таблицах, в 3-4 целочисленных поля. Если же зарядить запрос на таблицу с 50-ю полями и вытащить из неё записей тыщ двадцать, то вполне может оказаться, что материализация этих данных в объекты и есть главные тормоза.
Если нам не помогут, то мы тоже никого не пощадим.
Re[89]: Тормознутость и кривость linq
От: IT Россия linq2db.com
Дата: 01.05.16 18:23
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Имеем где-то порядка 2-12 микросекунд накладных расходов на простом запросе классического вида ради получения статически типизированного кода.


Что-то я не увидел тут статически типизированного кода. Голимые SQL строки.
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.