Re[67]: В России опять напишут новый объектно-ориентированны
От: IB Австрия http://rsdn.ru
Дата: 16.05.18 23:58
Оценка:
Здравствуйте, alex_public, Вы писали:

_> Вот на русском языке это звучит так: хотим получить массив, каждый элемент которого является усреднением соседей этого элемента в исходном двухмерном массиве. Вроде бы как раз описание желаемого результата, без каких-либо указаний о механизме реализации. Покажешь как это сформулировать на linq?

from Filter(data, filterType, parameters) select x,
пойдет? )

_>И в чём разница?

в том, что он и не должен мочь.

_>Ну для РСУБД это например все те, для которых сейчас применяется PL/SQL... )))

Не подходит, PL/SQL работает по готовым SQL запросам, а не лезет в потроха базы в обход sql.

_> А для вообще СУБД там будет ещё много чего интересного, в зависимости от конкретной задачи (см. разные nosql СУБД — в большинстве из них есть что-то своё, не реализуемое на SQL).

так что конкретно на sql не реализуется?

_>Более высокоуровневые чем OpenGL уже давно есть — это всяческие GUI библиотеки, игровые движки и т.п. Но их все просто переписали (точнее бэкенд в них, т.к. он и так был выделен в отдельную абстракцию в силу наличия в прошлом нескольких конкурирующих API, типа того же Direct3D) под новый более низкоуровневый API, потому что он дал большее быстродействие. Причём пользователи этих библиотек возможно даже не заметили разницу. Так как и пользователи различных ORM могут не заметить разницу при замене SQL на что-то более эффективное.

Не совсем так... пользователи SQL не замечают, когда разработчики СУБД увеличивают производительность и улучшают алгоритмы иногда полностью их меняя. Вот это более верная аналогия )
Мы уже победили, просто это еще не так заметно...
Re[48]: В России опять напишут новый объектно-ориентированны
От: IT Россия linq2db.com
Дата: 17.05.18 00:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В linq2db приходится через .ToCTE() записывать.


Переименовали в .GetCte(). Я думал вообще не возможно, но умельцы придумали
Если нам не помогут, то мы тоже никого не пощадим.
Re[66]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 10:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Давай всё же определимся. Если программист вставляет что-то подобное, то значит он знает что делает и это действительно лучшее решение. Иначе зачем ему это делать?

S>а) о думает, что знает лучше, но на самом деле не понимает подробности работы конвеера и кэша.
S>б) он в самом деле знал лучше, но это было актуально в далёком мае 2018; сейчас, в 2024, архитектура существенно изменилась, а статистика реального использования отличается от того, что ожидал программист.
S>Я работаю в коммерческой разработке софта с 1991 года. Представления о том, чего могут и чего не могут программисты — имею вполне статистически значимые.

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

_>>Вот тебе хорошо, т.к. тебе надо только "вверх" относительно SQL. А что предложишь делать тем, кому надо "вбок"? )

S>Для начала надо определить, что это за "вбок" такой. Невозможно решить несформулированную задачу.

Ну вот например я хочу не SQL, а такой https://www.opencypher.org/ язык для своей задачи. Тот же Hadoop/Spark это легко позволяют https://neo4j.com/blog/cypher-for-apache-spark/.

_>>Это не тупик, а это фундамент, на котором лежит весь мир IT. И да, чем больше мы создаём новых абстракций (а потом и абстракций поверх этих абстракций), тем меньше потребности к ручной правке этого фундамента. Но при этом он всегда в действие (исполняется именно такой код в итоге) и всегда под рукой для правки, если существующие абстракции не справляются.

S>Ну вот нет же. "всегда под рукой". Вот вам Node.js — пойдите, подтюньте поведение коллекций в нём, если вас не устраивает стандартный джаваскриптовый ассоциативный массив.

И в чём проблема https://habr.com/post/154007/ ? ) Ну естественно "подтюнивание" будет заключаться в написание своей коллекции, точно так же как написанный на C модуль numpy превращает медленный Питон в один из главных инструментов вычислений у учёных, инженеров, аналитиков, специалистов по машинному обучению и т.п.

_>>И как тебе roslyn поможет управлять локами в транзакции?

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

Что за хинты? Не видел такого в стандарте SQL...

Ну и проблем с парсерами SQL как бы никаких нет... )

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


Да, появление компилятора с открытым API — это хорошо. Помнится после появления Clang'а тоже появилось множество интересных инструментов. Однако не очень понятно какое это имеет отношение к нашей беседе.
Re[25]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 11:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>А какая связь между временем генерации SQL строки (одной и той же) и тем сколько времени будет её исполнять сервер?

S>Очень простая. Вот-простой пример:
S>
S>select * from order_items where order_id not in (select id from orders)
S>

S>Я могу отправить эту строку, и наслаждаться тем, как шустро сервер сканирует два индекса.
S>А могу проанализировать foreign key constraints, провести упрощение предиката, и никакой запрос на сервер вообще не отправлять. То есть имеем 100мс на анализ против 0мс на анализ и O(N) на исполнение запроса.

Так foreign key constraints задаются в коде или же берутся с сервера в рантайме?

_>>Возможно и не плохая. Если конечно нельзя сэкономить это лишнее обращение, не потратив 200мс.

S>Совсем ничего не потратить не получится.

Получится, если делать это во время компиляции (в идеале) или при инициализации приложения (вариант похуже, но всё равно лучше текущей реализации linq для СУБД).

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

S>А можно вкратце пояснить, чем, по-вашему, WASM лучше CLR или JVM?

Низкоуровневостью и следующей из неё универсальностью и эффективностью. Можно без проблем взять любой существующий C/C++ код (например ту же самую реализацию .net из mono, как сделали в проекте blazor) и просто скомпилировать его под WASM. Причём быстродействие будет всего раза в 2 хуже нативного кода (что гораздо лучше любых других безопасных решений, типа CLR и JVM).

_>>Ну так если мы говорим о передаче подобного императивного кода, то с ним напрямую справляются платформы типа Spark. Ну точнее вот это самое разделение одной функции на этапы делает сам программист, а вот потом этот код спокойно отсылается на исполнение сервером.

S>Это не совсем императивный код. В идеале, мы вообще хотим избавиться от императивного кода, потому что декларативный код позволяет нам точнее выражать намерения.
S>Современный компилятор тратит много времени на восстановление намерений автора по его коду, и не всегда успешно. Приходится ослаблять семантику кода, чтобы развязать руки оператору — отсюда всякие "порядок вычисления аргументов не определён" и прочие попытки сэкономить.

Что-то я не увидел никакой декларативности в этих твоих примерах. Ну и если ты называешь это декларативным, то и какой-нибудь Spark тоже получается таким. )))

_>>По-моему это не противоречащие друг другу пожелания.

S>В идеале — да. На практике их сочетание очень трудно получить. Вы попробуйте вручную пооптимизировать VMT в плюсах, чтобы понять, о чём идёт речь.

Хы, да есть решения даже покруче (типа нецелевого использования VMT), причём в базовых библиотеках от MS. А к примеру библиотека сопрограмм (stackful) из Буста опирается об ассемблерный код (написанный отдельно под каждую архитектуру процессоров) сохранения/восстановления регистров. И ничего страшного.

_>>Ну вот как мы тут выяснили, linq для коллекций точно не покрывает все интересные случаи.

S>Смотря что считать интересными случаями. Двумерный массив, к примеру, коллекцией в полном смысле не является.

Ну можешь посмотреть на него, как на вложенные коллекции — это сильно изменит ситуацию? )))

_>>Да, но при этом спектр охватываемых им задач меньше не только чем у тупого for, но даже меньше чем у цепочки range (тоже довольно абстрактной конструкции).

S>И даже меньше чем у набора из "0, инкремент, выбор N-го аргумента". Понятно, что чем "тупее" инструкция, тем "полнее" спектр охватываемых ею задач. Точнее, наоборот — не "охватываемых", а тех, куда её можно применить.

О том и речь. А поверх этого (не отключая возможность использования) можно строить (желательно с нулевым оверхедом) более высокоуровневые абстракции. Типа того же range.
Re[64]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 11:39
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Да, linq тут не у дел, а при этом тупой императивный for легко справляется и тут. Собственно именно об этом я писал изначально, но потребовалось как-то многовато времени и конкретных примеров, чтобы собеседники смогли ощутить это сами...

S>Легко — не значит хорошо.

Ну если смотреть по быстродействию, то не просто хорошо, а лучше всех. )))

S>Конкретного примера, кстати, так и нету.


Ты его сам же ниже написал, причём аж в одну строчку. )))

_>>Ну так никто не против таких подходов, только при правильной модели и реализации...

S>А с чем же тогда вы спорите?

Критика относилась непосредственно к Linq (неправильная модель и кривая реализация), а не к идее написания высокоуровневых абстракций.

Плюс я против идеи блокировки доступа к низкоуровневому коду после появления высокоуровневых абстракций, но это отдельный вопрос (в том же linq для коллекций такой блокировки нет, а вот у SQL есть).

S>Пока что видно, что вы неверно понимаете слово "эффективность". Вы занимаетесь микрооптимизациями — это крайне интересная область, но в распределённой среде важно не умение быстро выполнить миллион операций, а суметь выполнить только 10000 операций из них.


Вообще то как раз современные распределённые решения (они же все nosql) берут совершенно другим принципом. Там выполняется множество "ненужной" работы, но за счёт того, что это происходит на сотнях узлов, итоговый результат выдаётся всё равно быстрее чем у "умного" решения на одном сервере.

_>>Язык ничего не навязывает. Императивный for — это универсальный базовый кирпичик, с помощью которого можно эффективно решить любую задачу. Причём это может быть как конкретный частный случай (который возможно и имеет смысл решать в лоб), так и какой-то обобщённый фреймворк для всего класса подобных задач с неким DSL.

S>Ну вот вы же сами привели пример задачи, в которой for противопоказан.

For нигде не противопоказан. Мы или используем его сами или используем его внутри неких абстракций, представляющих собой уже готовые алгоритмы.
Re[71]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 11:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>https://docs.mongodb.com/manual/core/journaling/, https://docs.mongodb.com/manual/tutorial/manage-journaling/

И? Прямо по твоим ссылкам написано, что журнал работает как раз по умолчанию. А для отключения журналирования надо запускать Монгу со специальной опцией (я этого естественно не делал в тех тестах).

_>>Хы, помнится мы тут на форуме тестировали некий пример несколько лет назад и в нём Монга обходила MS SQL. При этом я запускал Монгу как раз в дефолтном режиме, без каких-то спец. опций.

S>Вот по умолчанию, если вручную при записи не требовать j:true, то монга выполняет коммит в памяти. Но,

Хм, вот насчёт j:true я уже не помню, использовалось ли оно в тех тестах или нет.
Re[75]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 11:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Или там есть какая-то волшебная механика распределения работы так, чтобы первый билет даже не пытался писаться на нодах 2 и 3, чтобы следующий клиент сразу мог писать в ноду 2, а третий — в ноду 3?




И ты только сейчас это понял??? Вообще то я уже давно и не раз писал именно об этом (как о причине появления современных nosql решений) в данной темке. И как раз именно ради этого и используется схема ключ->"что-то там".
Re[68]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 11:57
Оценка:
Здравствуйте, IT, Вы писали:

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

IT>Ого! Что я слышу. Ты прям звучишь как главный поборник и харикришна технической аргументации. Как я понимаю, самого тебя об этом просить бесполезно, т.к. ты у нас читатель, а не писатель. Ну да ладно, если у тебя у самого на столь элементарные примеры фантазии не хватает, то вот:
IT>
IT>var q =
IT>    from t in Table
IT>    where t.Field1 == GetWpfCustomeEditFormData().CustomerDataField
IT>    select new WpfCustomerViewModel(t.Field2, t.Field3);
IT>

IT>Оба метода в этом примере являются одновременно как частью запроса, так и уникальны для приложения, в котором этот запрос выполняется. Давай, передавай это всё на сервер и там разруливай.

Так это у тебя только пример "объявления AST", который может быть и вполне корректным для определённых задач (скажем при исполнение на клиенте). А где у тебя собственно код отправления этого запроса на сервер? Ведь именно там система должна послать тебя очень далеко (в идеале на стадии компиляции, но в текущей убогой реализации linq это видимо только в рантайме возможно)...

_>>Эм, ты какой-то странный. Я правильно понимаю, что если я захочу передать для выполнение на GPU код обращения к СУБД и компилятор пошлёт меня подальше с такими идеями, то это будет означать что я (или транслятор в CUDA? или кто?) обламался?

IT>Похоже ты абсолютно не въезжаешь в проблему.

Да, я не вижу абсолютно никакой проблемы в том, что система не будет позволять выполнять априори некорректный код. Так же как и на GPU тебе никто не позволит отослать неподходящий для этого код.

_>>Заглядывать в код сервера не нужно. Сервер очевидно должен предоставлять загружаемому коду некий API, так же как это делает сейчас например браузер. Именно поэтому я и говорил, что для подобного, API к РСУБД в виде SQL недостаточно. А вот при наличие более низкоуровневого API проблем очевидно уже не будет.

IT>Почему SQL недостаточно? И почему более низкоуровневый (это какой) API достаточно?

Ну у SQL то вообще всё тяжело, т.к. он не позволяет задавать даже не использующий внутренний API (грубо говоря чистую функцию), произвольный императивный код.
Re[70]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 12:44
Оценка:
Здравствуйте, Lexey, Вы писали:

_>>А то там на первой же картинке под названием "Архитектура YQL" красуются и Python и Jupyter...

L>Угу, первый в качестве одного из языков расширения и одного из публичных API, второй — в качестве одного из возможных UI. Если их выкинуть, работоспособность YQL практически никак не пострадает.

Да, только вот аналитикам этот самый YQL в таком случае будет уже не интересен, т.к. они в большинстве своём предпочитают именно Python (с соответствующими библиотеками и GUI) в роли центрального инструмента для своей работы. В который в одну команду импортируются данные и из YQL и из SQL и из cvs/excel и из SAP и из Hadoop и много чего ещё.

_>>В общем фееричное возражение у тебя получилось...

L>Ты его просто не понял. Статья вполне явно показывает, что в Яндексе тренд идет вовсе не в сторону отказа от SQLя в пользу питона, а, наоборот, в сторону создания "продвинутого SQLя", который позволяет решать многие задачи обработки данных вообще без питона, плюс позволяет интегрироваться с питоном, если возможностей одного YQLя недостаточно.

Хы, ты похоже вообще не в курсе темы.

У Яндекса не может быть отказов от SQL в сторону Питона или наоборот, потому как в основе у них лежит вообще другой инструмент. Их базис — это собственноручно написанное nosql решение по схеме MapReduce, работающее с C++ (в смысле не только само на нём написанное, но и выполняющее произвольный код в запросах). Т.е. это что-то вроде своего аналога Hadoop, только не с Java, а с C++. В какой-то момент им видимо надоело писать однотипный императивный код для шаблонных случаев и они захотели написать свой высокоуровневный язык запросов. Только не такой убогий, как SQL, а значительно лучше: там есть и исполнение произвольного императивного кода (причём аж на C++! Ну и на Питоне ещё, но это там реализовано как просто C++ функция с интерпретатором Питона) и MapReduce и декомпозиция запросов и ещё много чего интересного.

Но это всё касалось грубо говоря доступа к данным (по сути API к БД), а реальной обработкой данных современные аналитики предпочитают заниматься в Питоне и с помощью Jupyter Notebook. Только раньше им надо было в начале загрузить данные (с помощью низкоуровневой mapreduce команды, написанной на C++) из хранилища Яндекса в csv файлик, а потом импортировать его в Питон. А теперь они могут просто в одну строчку загрузить данные их хранилища данных Яндекса (точно так же как они привыкли это делать для любых SQL баз, Hadoop'a и т.п.).
Re[76]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 17.05.18 13:04
Оценка:
Здравствуйте, IB, Вы писали:

IB>Еще раз, медленно. Прислонять sql к hdfs для выбора файлов не надо, он там и так есть, прислонять его надо к содержимому этих самых файликов. Когда язык питон, а данные в csv или в json-e, то без вариантов, сидишь и скалдываешь. Вот был бы шарп, обрабатывали бы все linq-ом, а питон увы, до линка пока не дорос.


Основной инструмент Питона для работы с табличными данными называется pandаs, и именно он используется большинством аналитиков, учёных, инженеров и т.п. Так вот linq не идёт ни в какое сравнение с этим инструментом по удобству и эффективности работы.

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

IB>Совершенно верно, тенденции просматриваются. Например, тот же яндекс наелся ручного выпиливания питоном по csv и начал делать свой SQL-подобный язык, который обладает нужными свойствами. Действительно, люди хотят большего.

Действительно, импортировать сырые данные в Питон из своего nosql хранилища гораздо удобнее напрямую, а не через промежуточный csv файл. Но анализ данных то всё равно выполняется в Питоне, вне зависимости от способа импорта сырых данных.
Re[68]: В России опять напишут новый объектно-ориентированны
От: MadHuman Россия  
Дата: 17.05.18 14:18
Оценка:
Здравствуйте, IT, Вы писали:


IT>
IT>var q =
IT>    from t in Table
IT>    where t.Field1 == GetWpfCustomeEditFormData().CustomerDataField
IT>    select new WpfCustomerViewModel(t.Field2, t.Field3);
IT>


а разве такой запрос linq-провайдер под капотом автоматом не бъёт на две части? 1-я выполняется на сервере и возвращает список значений t.Field2, t.Field3.
и 2-я — локальная, по этому списку для каждого элемента и поднимает — new WpfCustomerViewModel(t.Field2, t.Field3) ?

даже если и нет (тут не уверен), ведь ни что не мешает сделать чтоб так могло бы быть... зачем вообще это — select new WpfCustomerViewModel(t.Field2, t.Field3); выполнять на сервере?
Re[69]: В России опять напишут новый объектно-ориентированны
От: IT Россия linq2db.com
Дата: 17.05.18 15:00
Оценка: +1
Здравствуйте, alex_public, Вы писали:

IT>>Оба метода в этом примере являются одновременно как частью запроса, так и уникальны для приложения, в котором этот запрос выполняется. Давай, передавай это всё на сервер и там разруливай.


_>Так это у тебя только пример "объявления AST", который может быть и вполне корректным для определённых задач (скажем при исполнение на клиенте). А где у тебя собственно код отправления этого запроса на сервер? Ведь именно там система должна послать тебя очень далеко (в идеале на стадии компиляции, но в текущей убогой реализации linq это видимо только в рантайме возможно)...


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

Про код отправки запроса на сервер компилятором я не всё понял, поэтому предположу, что ты имеешь ввиду генерацию компилятором некоего кода, который потом в рантайме будет отправлятся на сервер. Здесь я тебя должен огорчить, мой компиляторолюбивый друг, запросы вида

from t in Table where t.id == 1 select t


встречаются в демонстрационных примерах примерно на несколько порядков чаще, чем в реальном коде. В реальном коде мы наблюдаем чаще всего что-нибудь типа этого:

var q = from t in Table select t;

if (name.IsNotEmpty())
    q = q.Where(t => t.Name == name);

if (idList.IsNotEmpty())
    q =
        from t in q
        join id in IdTable on t.ID equals id.ID
        where id.ID.In(idList)
        select t;

var list q.ToList();


И это является одной из самых сильных сторон linq. Это позволяет строить более оптимальные запросы, которые при всей якобы медлительности linq, рвут по производительности всякие сохранённые процедуры и прямой SQL как тузик грелку.

Но при этом, всё, что может сделать компилятор — это сгенерировать промежуточное AST. Не готовый API для SQL, а AST этого кода, который ты уже в рантайм соберёшь в нечто более менее целое и сгенерируешь свой API для SQL. И если пойдёшь таким путём, то всё будет хорошо. Только есть одно но — ты только что изобрёл LINQ over WCF. Там всё именно так и работает.

IT>>Похоже ты абсолютно не въезжаешь в проблему.

_>Да, я не вижу абсолютно никакой проблемы в том, что система не будет позволять выполнять априори некорректный код. Так же как и на GPU тебе никто не позволит отослать неподходящий для этого код.

Никто — это для меня слишком абстракто. Кто именно никто?

IT>>Почему SQL недостаточно? И почему более низкоуровневый (это какой) API достаточно?

_>Ну у SQL то вообще всё тяжело, т.к. он не позволяет задавать даже не использующий внутренний API (грубо говоря чистую функцию), произвольный императивный код.

Зачем? Кому это надо?
Если нам не помогут, то мы тоже никого не пощадим.
Re[69]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.05.18 16:21
Оценка:
Здравствуйте, MadHuman, Вы писали:
MH>даже если и нет (тут не уверен), ведь ни что не мешает сделать чтоб так могло бы быть... зачем вообще это — select new WpfCustomerViewModel(t.Field2, t.Field3); выполнять на сервере?
Вот тут-то и начинаются грабли. Потому что linq-провайдер внезапно должен как-то понять, что, скажем, MD5() можно и нужно вычислить на сервере, а не тащить все миллионы записей в память для локального вычисления предиката.
А что-то другое — нужно и можно откладывать до приезда данных в клиента.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[70]: В России опять напишут новый объектно-ориентированны
От: MadHuman Россия  
Дата: 17.05.18 16:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, MadHuman, Вы писали:

MH>>даже если и нет (тут не уверен), ведь ни что не мешает сделать чтоб так могло бы быть... зачем вообще это — select new WpfCustomerViewModel(t.Field2, t.Field3); выполнять на сервере?
S>Вот тут-то и начинаются грабли. Потому что linq-провайдер внезапно должен как-то понять, что, скажем, MD5() можно и нужно вычислить на сервере, а не тащить все миллионы записей в память для локального вычисления предиката.
линк-провайдер же уже умеет понимать — поддерживает ли скл-сервер конкретную функцию. нет с этим проблемы. есть проблема, что если скл не поддерживает придётся тащить, ну тут либо поддержать функцию на скл-сервере либо тащить данные и локально фильтровать.
Re[69]: В России опять напишут новый объектно-ориентированны
От: IT Россия linq2db.com
Дата: 17.05.18 17:13
Оценка: 12 (4) +1 :)
Здравствуйте, MadHuman, Вы писали:

MH>а разве такой запрос linq-провайдер под капотом автоматом не бъёт на две части? 1-я выполняется на сервере и возвращает список значений t.Field2, t.Field3.

MH>и 2-я — локальная, по этому списку для каждого элемента и поднимает — new WpfCustomerViewModel(t.Field2, t.Field3) ?

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

Может ли такое же сделать компилятор? Конечно, может. В теории. Хотя нет. На практике тоже может, но, как я уже говорил, с большими ограничениями.

Есть три варианта решения проблемы.

1. Компилятор запрещает всякие вольности. Код формируется исключительно в заранее определённых терминах. Всё замечательно работает, но получаем серьёзные ограничения. Например, до свидания декомпозиция запросов, даже с помощью конкатенации строк. Такой подход реализован в Немерле в SQL macros. Этот макрос так и не прижился из-за своих ограничений и используется только как демонстрация немалых возможностей языка.

2. Всё, что есть компилятор заворачивает в специальный API и отправляет на сервер, а у сервера голова большая, он там сам со всем разбирается. Проблему мы уже обсудили — неизбежные паровозы.

3. Компилятор самостоятельно отделяет мух от котлет и на сервер едет что-то одно, либо мухи, либо котлеты.

В этом случае мы получаем сразу массу незабываемых впечатлений. Например, возьмём метод string.Length. Где его выполнять, на клиенте или на сервере? Очевидно, в случае

where Field1.Length > 0


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

Тут сразу хотелось бы отметить следующую особенность SQL — многообразие диалектов. Вот как выглядит метаинформация этого метода в linq2db

[Sql.Function  (                                                   PreferServerSide = true)]
[Sql.Function  (PN.Access,    "Len",                               PreferServerSide = true)]
[Sql.Function  (PN.Firebird,  "Char_Length",                       PreferServerSide = true)]
[Sql.Function  (PN.SqlServer, "Len",                               PreferServerSide = true)]
[Sql.Function  (PN.SqlCe,     "Len",                               PreferServerSide = true)]
[Sql.Function  (PN.Sybase,    "Len",                               PreferServerSide = true)]
[Sql.Function  (PN.MySql,     "Char_Length",                       PreferServerSide = true)]
[Sql.Expression(PN.DB2LUW,    "CHARACTER_LENGTH({0},CODEUNITS32)", PreferServerSide = true)]
public static int? Length(string str)
{
    return str == null ? null : (int?)str.Length;
}


И это всего лишь детские шалости в сравнении, например, с методом DatePart, где у нас полный

  адъ и израиль
[CLSCompliant(false)]
[Sql.Function]
[Sql.DatePart(PN.DB2,        "{0}",                                         false, new[] { null,     null,  null,   null,      null,   null,  "DayOfWeek", null,     null,   null,   null   }, 0, 1)]
[Sql.DatePart(PN.Informix,   "{0}",                                                0, 1)]
[Sql.DatePart(PN.MySql,      "Extract({0} from {{0}})",                     true,  0, 1)]
[Sql.DatePart(PN.PostgreSQL, "Cast(Floor(Extract({0} from {{0}})) as int)", true,  new[] { null,     null,  null,   "DOY",     null,   null,   "DOW",      null,     null,   null,   null   }, 0, 1)]
[Sql.DatePart(PN.Firebird,   "Cast(Floor(Extract({0} from {{0}})) as int)", true,  new[] { null,     null,  null,   "YearDay", null,   null,   null,       null,     null,   null,   null   }, 0, 1)]
[Sql.DatePart(PN.SQLite,     "Cast(StrFTime({0}, {{0}}) as int)",           true,  new[] { "'%Y'",   null,  "'%m'", "'%j'",    "'%d'", "'%W'", "'%w'",     "'%H'",   "'%M'", "'%S'", "'%f'" }, 0, 1)]
[Sql.DatePart(PN.Access,     "DatePart({0}, {{0}})",                        true,  new[] { "'yyyy'", "'q'", "'m'",  "'y'",     "'d'",  "'ww'", "'w'",      "'h'",    "'n'", "'s'",   null   }, 0, 1)]
[Sql.DatePart(PN.SapHana,    "{0}",                                         true,  new[] { "Year({0})",                       "Floor((Month({0})-1) / 3) + 1", "Month({0})",                     "DayOfYear({0})",                "DayOfMonth({0})",               "Week({0})",                     "MOD(Weekday({0}) + 1, 7) + 1",                  "Hour({0})",                       "Minute({0})",                   "Second({0})",                   null },                            0, 1)]
[Sql.DatePart(PN.Oracle,     "{0}",                                         true,  new[] { "To_Number(To_Char({0}, 'YYYY'))", "To_Number(To_Char({0}, 'Q'))",  "To_Number(To_Char({0}, 'MM'))", "To_Number(To_Char({0}, 'DDD'))", "To_Number(To_Char({0}, 'DD'))", "To_Number(To_Char({0}, 'WW'))", "Mod(1 + Trunc({0}) - Trunc({0}, 'IW'), 7) + 1", "To_Number(To_Char({0}, 'HH24'))", "To_Number(To_Char({0}, 'MI'))", "To_Number(To_Char({0}, 'SS'))", "To_Number(To_Char({0}, 'FF'))" }, 0, 1)]
public static int? DatePart(DateParts part, DateTime? date)


Где брать эту метаинформацию? Лепить атрибуты к самому методу? Т.е. .NET фреймворк в целом и System.String в частности должен знать всё о каком-то там InterBase? А если не знает, то этот сервер не достоин? Чушь. Тогда давайте эту информацию затолкаем в сам компилятор. Ну а чо? Пусть компилятор знает всё об InterBase, например. И что, что у этой базы всех вместе аж целых полтора клиента? Он же компилятор. К тому же он должен знать не только об InterBase, но и обо всех его версиях, как старых, так и новых. И код должен генерировать под ту версию базы, которая стоит у клиента. А если клиент обновится, то купит у разработчика новую перекомпилированную версию приложения. Хотя нет, у продвинутого разработчика уже готовы и скомпилированы все возможные варианты приложения под все базы и под все их версии. Хотите свеженький PostgreSQL? Просим в кассу.

И вот ещё, кстати. Sybase не умеет TOP(n) в подзапросах. У нас на дворе конец 10-х 1-го века 2-го тысячелетия, а Sybase не умеет. Все умеют, а Sybase не умеет. Вопрос, должен ли компилятор выдавать в такой ситуации одну ошибку на всех или только на Sybase? А что тогда в случае Sybase будут продавать наши продвинутые разработчики? Или они самоограничаться неиспольованием TOP(n) в подзапросах?

Очевидно, что это не самый лучшый подход. Давайте вмето этого соберём всех разработчиков БД и попросим их не страдать фигнёй и упразнить свои диалекты, вместо них разработать унифицированный API, дописать недостающего или если кто-то не может, то всем остальным отказаться от этих фич. Ну да. Иначе наш компилятор не сможет обеспечить. Ответ я примерно представляю:

— Really? Listen to me now, baby. Go away and never come back.

Это наиболее вежливая форма.

Итак, что мы имеем. Компилятор должен где-то брать метаинформацию для генерации API. Компилятор должен учитывать особенности разных БД (ну или провести разъяснительную работу среди разработчиков БД). И ещё желательно, чтобы компилятор умел на ходу расширяться.

Кто сказал, что метод WpfCustomerViewModel не может быть сконвертирован в SQL? Вообще-то, в linq2db такая фигня делается на раз-два. Т.е. компилятор ко всему прочему должен ещё и уметь легко расширятся по первому требованию.

Вы всё ещё верите в эту чушь?

Ну тогда контрольный в голову (хотя это уже было). Скомпилируйте готовый API вот для такого кода:

var q = from t in Table select t;

if (name.IsNotEmpty())
    q = q.Where(t => t.Name == name);

if (idList.IsNotEmpty())
    q =
        from t in q
        join id in IdTable on t.ID equals id.ID
        where id.ID.In(idList)
        select t;

var list q.ToList();


Нет? А чо так? Что? Так не честно, вам для компиляции нужен целыный законченный запрос? Ну простите. Давайте перенесём генерацию API в рантайм? Давайте. А что будет генерировать компилятор для этого кода? Промежуточное AST. Понятно. Т.е. компилятор будет генерировать Expression Tree. Поздравляю, вы только что изобрели компилятор C#.
Если нам не помогут, то мы тоже никого не пощадим.
Re[67]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.05.18 17:38
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну так если проблем нет, то почему я не вижу кода обсуждаемых примеров? В чём проблема "описать на linq желаемый результат"? Вот на русском языке это звучит так: хотим получить массив, каждый элемент которого является усреднением соседей этого элемента в исходном двухмерном массиве. Вроде бы как раз описание желаемого результата, без каких-либо указаний о механизме реализации. Покажешь как это сформулировать на linq?

Ну ладно, уговорил.
Вот как это выглядит на linq:
var data = new int[10, 10];
var t1 = from d in data group d by (d[-1, 0] + d[1, 0] + d[0, -1] + d[0, 1]) / 4;
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[72]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.05.18 17:39
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И? Прямо по твоим ссылкам написано, что журнал работает как раз по умолчанию.

И при этом без явного указанbя j:true "коммит" происходит в памяти. Это — ровно то, о чём я говорил.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: В России опять напишут новый объектно-ориентированны
От: Danchik Украина  
Дата: 17.05.18 17:43
Оценка: 11 (4)
Здравствуйте, alex_public, Вы писали:

[Проскипано куча теоретического овна]

_>>>Ну в чём-то лучше, а в чём-то хуже (те же CTE с рекурсией).

S>>Ну, пока что их реализация в linq2db выглядит вполне пристойно.

_>Какая ещё реализация? Судя по сообщениям в данной темке оно ещё только в разработке пока.


Пока вы тут с vdimas языками чешете, мы его уже зарелизили: https://github.com/linq2db/linq2db/wiki/CTE
Re[71]: В России опять напишут новый объектно-ориентированны
От: Lexey Россия  
Дата: 17.05.18 17:52
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Да, только вот аналитикам этот самый YQL в таком случае будет уже не интересен


Будет он им интересен. Просто потому, что он позволяет делать выборки и трансформацию данных из пачки источников без написания зубодробильного кода.
А вот результаты этого уже можно грузить куда угодно.

_>Хы, ты похоже вообще не в курсе темы.




_>У Яндекса не может быть отказов от SQL в сторону Питона или наоборот, потому как в основе у них лежит вообще другой инструмент. Их базис — это собственноручно написанное nosql решение по схеме MapReduce, работающее с C++ (в смысле не только само на нём написанное, но и выполняющее произвольный код в запросах). Т.е. это что-то вроде своего аналога Hadoop, только не с Java, а с C++. В какой-то момент им видимо надоело писать однотипный императивный код для шаблонных случаев и они захотели написать свой высокоуровневный язык запросов. Только не такой убогий, как SQL, а значительно лучше: там есть и исполнение произвольного императивного кода (причём аж на C++! Ну и на Питоне ещё, но это там реализовано как просто C++ функция с интерпретатором Питона) и MapReduce и декомпозиция запросов и ещё много чего интересного.


О, ты, похоже, слышал про YT. А слышал ли ты, что кроме него есть еще минимум 2 другие MR-системы. Это не считая реляционных баз и всяких key-value хранилищ.
Любая приличная реализация SQL умеет UDF, которые, внезапно, можно писать на плюсах (Яве, Шарпе, etc). В YQL оно работает ровно так же. Хочешь исполнять код на плюсах или питоне — пиши UDF с довольно жестким интерфейсом.

_>Но это всё касалось грубо говоря доступа к данным (по сути API к БД), а реальной обработкой данных современные аналитики предпочитают заниматься в Питоне и с помощью Jupyter Notebook.


Получение и подготовка данных — это, внезапно, часть реальной обработки, без которой ты никуда не уедешь.

_>Только раньше им надо было в начале загрузить данные (с помощью низкоуровневой mapreduce команды, написанной на C++) из хранилища Яндекса в csv файлик, а потом импортировать его в Питон. А теперь они могут просто в одну строчку загрузить данные их хранилища данных Яндекса (точно так же как они привыкли это делать для любых SQL баз, Hadoop'a и т.п.).


А ничего, что CSV-файлик на десяток терабайт может получиться, например? Долго его питону будешь скармливать?
"Будь достоин победы" (c) 8th Wizard's rule.
Отредактировано 17.05.2018 18:16 Lexey . Предыдущая версия .
Re[67]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.05.18 17:54
Оценка:
Здравствуйте, alex_public, Вы писали:
_>Ну квалификация энтерпрайзных программистов всегда была не высокой. Но это не значит, что надо ровнять всю индустрию на них.
Дело не в квалификации. Вам кажется, что квалификация — это неспособность сделать ошибку. Вовсе нет. Квалификация не означает всеведения или способностей предугадывать будущее.

_>Ну вот например я хочу не SQL, а такой https://www.opencypher.org/ язык для своей задачи. Тот же Hadoop/Spark это легко позволяют https://neo4j.com/blog/cypher-for-apache-spark/.

Это интересная инициатива. Но, во-первых, это по-прежнему декларативный язык, то есть непринципиально отличающийся от SQL, а во-вторых, я ещё не убедился, что он чем-то сильно лучше.
В-третьих, если вы хотите гонять его поверх RDBMS, то скорее всего, его не очень трудно просто транслировать в SQL. Без какой-либо потери производительности.

_>И в чём проблема https://habr.com/post/154007/ ? )

_>Ну естественно "подтюнивание" будет заключаться в написание своей коллекции, точно так же как написанный на C модуль numpy превращает медленный Питон в один из главных инструментов вычислений у учёных, инженеров, аналитиков, специалистов по машинному обучению и т.п.
Нет, так — не сработает. Либо работать будет не быстрее, чем встроенные коллекции, либо сломается интероперабельность. И вам весь-весь код придётся писать самому и с нуля.

_>>>И как тебе roslyn поможет управлять локами в транзакции?

S>>рослин — никак. А вот если бы у меня был под рукой готовый парсер SQL, то я бы мог писать несложные правила анализа, позволяющие мне автоматически расставлять хинты.
_>Что за хинты? Не видел такого в стандарте SQL...
Мы же работаем не со стандартом, а с конкретным сервером.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.