Re[57]: В России опять напишут новый объектно-ориентированны
От: MadHuman Россия  
Дата: 26.04.18 09:37
Оценка:
Здравствуйте, alex_public, Вы писали:

_>У linq есть множество очевидных недостатков. Причём как концептуальных (как раз связанных с моделью SQL),


можете назвать самые важные концептуальные?
Re[57]: В России опять напишут новый объектно-ориентированны
От: Ночной Смотрящий Россия  
Дата: 26.04.18 20:38
Оценка:
Здравствуйте, alex_public, Вы писали:

_>У linq есть множество очевидных недостатков. Причём как концептуальных (как раз связанных с моделью SQL)


У линка своя собственная модель, отличающаяся от sql. Сколько еще можно чушь писать?
Re[12]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.04.18 04:14
Оценка: +2
Здравствуйте, alex_public, Вы писали:
_>Однако эту ситуацию можно найти практически в любой СУБД (где есть записываемые на диск индексы) и это всего лишь один из примеров (просто очень близкий к обсуждаемой теме).
В нормальной СУБД движок не работает с объектами типа int[] или char*, которые нужно приводить к уместным типам по месту, а инварианты существуют только в голове разработчика.

_>Да можно даже и без юнит-тестов. На мой взгляд вполне достаточно использование соответствующего говорящего типа, пускай он и всего лишь синоним обычного массива (это я про typedef vector my_sorted_vector). Так то у программиста всегда есть способы сломать код, сделав что-то запрещённое правилами, но мы же не рассматриваем все подобные сценарии как реальные...

И очень зря вы их не рассматриваете. Пока прогрессивное человечество ищет способы массово внедрить non-nullable references, вы предлагаете сделать шаг назад к тем временам, когда время компилятора было дорогим, а программиста — дешёвым.

_>С линейный поиском то понятно. Я говорю про оверхед относительно двоичного поиска, но без linq. )

Оверхед от линка связан не с синтаксисом линка. Если мы обсуждаем гипотетические "языки будущего", то этот оверхед вообще неинтересен.

_>Чтобы была эффективность уровня C++, необходима возможность написания кода такого уровня абстракции:

_>
_>int a[]={1, 2, ...};//специально взял не C++, а C массив 
_>auto r=iterator_range(a, a+sizeof(а)/sizeof(a[0]));
_>auto x=my_search(r, 100);
_>...
_>template<...>
_>my_search(R r, T v)
_>{
_>    auto it=begin(r);
_>    auto x=*(it+10);//этот код должен быть идентичен на уровне ассемблера коду x=a[10];
_>}
_>

Нет, вот именно такой код ни в коем случае писать нельзя. Потому, что это прямая дорога к buffer overrun, эксплойтам и прочим spectre с meltdown-ами. Весь доступ к диапазону должен быть обложен проверками. Устранять излишние проверки — это да, это хорошо. Причём с точки зрения уязвимостей процессорного уровня вообще перед разыменованием указателя надо делать mod Length, чтобы предвыборка даже в кэш не помещала чужие данные.

_>Я не изучал насколько реально реализовать подобное на языках типа C#. Однако в C++ это не просто реализуемо в теории, но и вполне себе существует на практике и не первый год. Единственные нюанс, который можно отметить в этих реализациях: код этой самой сторонней библиотеки с where на C++ реализуется через шаблоны.

Дело не в шаблонах, а в наличии всех исходников в момент компиляции. Ну, и в том, что компилятор С++ может себе позволить потратить несколько часов на агрессивные оптимизации.
В управляемой среде перспективная техника — это hotspotting, спекулятивные оптимизации, и постепенный прогрев. Теоретически, он может дать выхлоп лучше, чем С++, но на практике этим никто уже не занимается лет десять.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[57]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.04.18 05:12
Оценка: +5
Здравствуйте, alex_public, Вы писали:

_>Не в качестве образца, а в качестве источника идей. Т.е. на мой взгляд при разработке новой технологии/языка надо брать всё лучшее из уже существующих. И идея о передаче произвольного императивного кода в запросе — одна из таких идей. Которую кстати можно увидеть во многих nosql решениях.

Это — категорически плохая идея. Для "произвольного императивного кода" крайне сложно проводить трансформации, нужные для оптимизаций. В первую очередь потому, что доказательства эквивалентности для него постоянно упираются в проблему останова.
Сложность — в выборе подходящих ограничений на пользовательский код, который будет исполняться сервером.
Этот код должен быть всё ещё достаточно выразительным, чтобы покрывать реальные сценарии, и достаточно ограниченным, чтобы оптимизатор мог применять глубокие трансформации.
Скажем, самый тупой движок современной РСУБД в состоянии самостоятельно выбрать индекс для того, чтобы ускорить отбор по предикату.
А самый умный компилятор С++ не в состоянии без подсказки заменить линейный поиск на бинарный в выбранном нами случае.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[57]: В России опять напишут новый объектно-ориентированны
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 27.04.18 11:53
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Он сказал дословно:

_>

_>Да, для работы с массивами интов линк малополезен.


И дополним цитату из контекста:

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


«Поздравляю вас, гражданин соврамши!» @


_>и предложил рассмотреть другие задачи. С которыми тоже в итоге оказалось всё гораздо сложнее, но там хотя бы было поле для дискуссии... )))


Ога. Процитирую Синклера:

И он так и будет отставать на один шаг. В итоге у нас при честном сравнении быстродействия, "декларативное решение" будет всё время впереди.
А императивное будет бежать за ним, задыхаясь, и кричать "подождите, я вам сейчас на рояле поиграю!"


Смачно написано, легко запомнить. Похоже. что ты это или не понял, или не читал
Re[58]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 01.05.18 22:26
Оценка: -2
Здравствуйте, MadHuman, Вы писали:

_>>У linq есть множество очевидных недостатков. Причём как концептуальных (как раз связанных с моделью SQL),

MH>можете назвать самые важные концептуальные?

Тут надо разделить недостатки в работе с коллекциями и в работе с СУБД. Хотя уже собственно в этом наблюдается один из важнейших концептуальных недостатков — попытка объединить универсальным интерфейсом настолько разные вещи. Но это так сказать общие слова, а нам нужны детали. Значит по пунктам:

— работа с коллекциями. Тут как раз главным недостатком является попытка использования модели SQL, которая в силу своей функциональной природы является сильно ограниченной по сравнению с классическим императивным кодом. Более того, используемая для работы с коллекциями реализация (IEnumerable) является даже более ограниченной (только последовательный доступ), чем классический SQL, для которого в СУБД происходит интерпретация в императивный код. Уже даже в этой дискуссии было упомянуто минимум три конкретных примера, в которых наблюдаются серьёзные проблемы: использования вычислений из соседних итерация ("строк"), использование отсортированных коллекций, использование коллекций типа деревьев и других вариаций на тему графов. А уж если вспомнить про множество задач с рекурсиями... В общем думаю тут можно придумывать такие примеры тысячами, просто в силу ограниченности изначального подхода. Точнее в теории ещё можно было бы попробовать сделать реализацию в духе СУБД, только с интерпретацией Linq кода на этапе компиляции по заданным метаправилам — тогда это могло бы охватить гораздо более широкий диапазон задач (хотя всё равно не все), но для этого требуется как минимум язык с наличием развитого метапрограммирования.

— работа с СУБД. Тут опять же следует разделить вопрос на два подпункта.

Если рассматривать Linq, исключительно как генератор SQL (т.е. считая что SQL сам по себе идеален для любых подобных задач), то понятно что концептуально тут к Linq не может быть никаких претензий, банально в силу схожести моделей. Ну точнее в конкретных реализациях там до сих пор имеются проблемы (типа отсутствия поддержки CTE, оверхеда рантаймовой генерации на каждом запросе и т.п.), но вопрос был про концептуальные проблемы, а тут их очевидно нет.

Если же рассматривать Linq, как инструмент работы с СУБД, то тут Linq автоматически наследует все концептуальные проблемы SQL. Причём даже в ещё худшей степени, т.к. например большинство РСУБД помимо SQL поддерживают ещё какой-то свой императивный язык (интегрируемый с SQL), ну а у Linq с этим естественно никак. Что уж тут говорить о поддержке наиболее активно развиваемых сейчас распределённых вычислений (СУБД на базе hadoop и т.п.), в которых уже даже MapReduce становится устаревшим (см. Spark).
Re[13]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 01.05.18 22:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>В нормальной СУБД движок не работает с объектами типа int[] или char*, которые нужно приводить к уместным типам по месту, а инварианты существуют только в голове разработчика.

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

_>>Да можно даже и без юнит-тестов. На мой взгляд вполне достаточно использование соответствующего говорящего типа, пускай он и всего лишь синоним обычного массива (это я про typedef vector my_sorted_vector). Так то у программиста всегда есть способы сломать код, сделав что-то запрещённое правилами, но мы же не рассматриваем все подобные сценарии как реальные...

S>И очень зря вы их не рассматриваете. Пока прогрессивное человечество ищет способы массово внедрить non-nullable references, вы предлагаете сделать шаг назад к тем временам, когда время компилятора было дорогим, а программиста — дешёвым.

Не имею ничего против любых "защит", встраиваемых в язык/компилятор, при условие, что это не приводит к дополнительному оверхеду. Т.е. если говорить например о классической проблеме опасных указателей из языка C, то на мой вкус решение в виде языка Java плохое, а решение в виде языка Rust хорошее...

_>>С линейный поиском то понятно. Я говорю про оверхед относительно двоичного поиска, но без linq. )

S>Оверхед от линка связан не с синтаксисом линка. Если мы обсуждаем гипотетические "языки будущего", то этот оверхед вообще неинтересен.

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

_>>Чтобы была эффективность уровня C++, необходима возможность написания кода такого уровня абстракции:

_>>
_>>int a[]={1, 2, ...};//специально взял не C++, а C массив 
_>>auto r=iterator_range(a, a+sizeof(а)/sizeof(a[0]));
_>>auto x=my_search(r, 100);
_>>...
_>>template<...>
_>>my_search(R r, T v)
_>>{
_>>    auto it=begin(r);
_>>    auto x=*(it+10);//этот код должен быть идентичен на уровне ассемблера коду x=a[10];
_>>}
_>>

S>Нет, вот именно такой код ни в коем случае писать нельзя. Потому, что это прямая дорога к buffer overrun, эксплойтам и прочим spectre с meltdown-ами. Весь доступ к диапазону должен быть обложен проверками. Устранять излишние проверки — это да, это хорошо. Причём с точки зрения уязвимостей процессорного уровня вообще перед разыменованием указателя надо делать mod Length, чтобы предвыборка даже в кэш не помещала чужие данные.

Ну так и никто не мешает тебе вставить в своём коде алгоритма поиска соответствующую проверку (типа "if(end(r)-begin(r)<10) ..."), с нужными для твоего алгоритма результатами. И эта проверка тоже не будет нести ни капли оверхеда.

_>>Я не изучал насколько реально реализовать подобное на языках типа C#. Однако в C++ это не просто реализуемо в теории, но и вполне себе существует на практике и не первый год. Единственные нюанс, который можно отметить в этих реализациях: код этой самой сторонней библиотеки с where на C++ реализуется через шаблоны.

S>Дело не в шаблонах, а в наличии всех исходников в момент компиляции. Ну, и в том, что компилятор С++ может себе позволить потратить несколько часов на агрессивные оптимизации.
S>В управляемой среде перспективная техника — это hotspotting, спекулятивные оптимизации, и постепенный прогрев. Теоретически, он может дать выхлоп лучше, чем С++, но на практике этим никто уже не занимается лет десять.

А вот тут ты как раз принципиально ошибаешься. Ты путаешь принципиальное отсутствие оверхеда у определённых видов абстракции в определённых языках и работу оптимизатора. В том то и заключается ключевой нюанс, что вышеприведённый код будет идентичен a[10] даже при полностью выключенных опциях оптимизации — это гарантированная особенность реализации, а не надежда на хорошую оптимизацию. Как раз последнее в C++ уже давно никто не берётся предсказывать с гарантией, т.к. поведение оптимизатора очень сложно и сильно зависит от окружающих условий (например один и тот же код может илайниться, а может и нет, в зависимости от окружения). А вот гарантию отсутствия оверхеда в описанном случае можно легко дать, т.к. это не оптимизация!
Re[58]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 01.05.18 23:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Не в качестве образца, а в качестве источника идей. Т.е. на мой взгляд при разработке новой технологии/языка надо брать всё лучшее из уже существующих. И идея о передаче произвольного императивного кода в запросе — одна из таких идей. Которую кстати можно увидеть во многих nosql решениях.

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

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

S>Скажем, самый тупой движок современной РСУБД в состоянии самостоятельно выбрать индекс для того, чтобы ускорить отбор по предикату.

S>А самый умный компилятор С++ не в состоянии без подсказки заменить линейный поиск на бинарный в выбранном нами случае.

Однако сейчас идёт активное развитие именно таких подходов. Посмотри на СУБД вокруг Hadoop. Там же прямо эта идея работает и при этом как раз этими СУБД частенько заменяют реляционные хранилища данных.
Re[18]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 02.05.18 22:48
Оценка: -2
Здравствуйте, MTD, Вы писали:

MTD>Нет, ты даже не понял, что код делает.


В системе оценок RSDN явно не хватает оценки за наивность.
Ты действительно считаешь так, как здесь написал?
Потому что до этого я обвинил тебя в том, что ты слишком много пишешь "в пику", т.е. пишешь заведомый информацонный мусор.
Но если подобные закидоны у тебя не в пику, а вполне искренние — то ой.
Re: Проблемы современных СУБД
От: BOBKA_XPEH Новая Зеландия  
Дата: 02.05.18 22:52
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Потому что SQL безбожно устарел и вообще в современной разработке является сущностью второго рода...


Будь проще, напиши так — "Помогите освоить SQL."
Гей хлопци — шлях в Европу!
Re[14]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.05.18 03:47
Оценка: +1
Здравствуйте, alex_public, Вы писали:

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

Демагогия — это сравнивать однократное приведение отмапленных из файла страниц к (IndexPageHeader*) c повсеместным применением upper_bound к произвольным итераторам, происхождение которых по коду отследить невозможно.

_>Не имею ничего против любых "защит", встраиваемых в язык/компилятор, при условие, что это не приводит к дополнительному оверхеду. Т.е. если говорить например о классической проблеме опасных указателей из языка C, то на мой вкус решение в виде языка Java плохое, а решение в виде языка Rust хорошее...

Увы, с растом не знаком.

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

Брр. Попробую по буквам: в linq так и формируется "соответствующий императивный код". Query comprehension — это всего лишь сахар для построения определённой цепочки вызовов. Нет никакой "невозможности зашить в компилятор" — компилятор С++ прекрасно порождает высокоэффективный код из подобных цепочек вызовов, а компиляторы, которые порождают Execution Plan из SQL Query в современных RDBMS успешно применяют метаданные типа кардинальности связей, ограничения и прочее при выборе стратегий исполнения на лету.

_>Ну так и никто не мешает тебе вставить в своём коде алгоритма поиска соответствующую проверку (типа "if(end(r)-begin(r)<10) ..."), с нужными для твоего алгоритма результатами. И эта проверка тоже не будет нести ни капли оверхеда.

А ещё можно просто вручную отсортировать массив констант. Мы же говорим о применении компьютера. Я не собираюсь полагаться на то, что программист записал всё верно, и наша магическая константа везде равна именно 10, а не 010, написанные по ошибке в одном из мест использования. Чтобы "соответствующая проверка" не несла ни капли оверхеда, компилятор должен быть очень умным — в частности, уметь доказывать теоремы для устранения избыточных проверок.
При этом для банальных сценариев типа индексации массива в цикле устранение избыточных проверок уже делают все современные JIT-компиляторы — и для Java, и для .Net.

_>А вот тут ты как раз принципиально ошибаешься. Ты путаешь принципиальное отсутствие оверхеда у определённых видов абстракции в определённых языках и работу оптимизатора. В том то и заключается ключевой нюанс, что вышеприведённый код будет идентичен a[10] даже при полностью выключенных опциях оптимизации — это гарантированная особенность реализации, а не надежда на хорошую оптимизацию.

Да ничего я не путаю.
Во-первых, тождество a[x]==*(a+x) работает только для встроенных массивов. Как только в качестве a у нас выступает пользовательский тип, обеспечение эквивалентности операторов [] и + начинает полагаться на совесть программиста. Более того, если отключить прямо все-все оптимизации, то ассемблерный код станет резко другим — ведь нам будет запрещено инлайнить код операторов, которые были определены для класса итератора. Поэтому там будет честный call, вместо ADD 0xA, которого вы наивно ожидаете.
Во-вторых, такой выбор семантики — плох. То есть одно дело — адресная арифметика, которая заведомо небезопасна (именно поэтому в дотнете она доступа только в unsafe-регионах). А другое дело — индексация массива, которую можно и нужно делать безопасной. Под безопасностью здесь подразумеваются гарантии невылета за пределы "нашей" памяти и отсутствия реинтерпретации данных (type safety).
_>Как раз последнее в C++ уже давно никто не берётся предсказывать с гарантией, т.к. поведение оптимизатора очень сложно и сильно зависит от окружающих условий (например один и тот же код может илайниться, а может и нет, в зависимости от окружения). А вот гарантию отсутствия оверхеда в описанном случае можно легко дать, т.к. это не оптимизация!
Ваше представление об abstraction penalty весьма наивно, простите.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[59]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.05.18 03:52
Оценка:
Здравствуйте, alex_public, Вы писали:

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

Как правило — нет. Я видел всего несколько сценариев, где обыграть MS SQL образца 2005 года было реально (причём я себя считаю очень крутым DBA)
Кроме того, пакость — в том, что у человека обычно меньше "знания соответствующих особенностей наборов данных", чем у RDBMS.
Если ты спросишь у менеджера, каково характерное количество строк в заказе, то он скорее всего ошибётся на порядок. В любую сторону.
Просто потому, что его восприятие искажено. СУБД не подвержено всем вот этим вот observation bias, и точно знает, сколько где там чего.

Про Hadoop было бы неплохо почитать какие-нибудь success stories, где люди рассказывают в подробностях, что именно заменили, каким способом, и почему.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 03.05.18 22:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Демагогия — это сравнивать однократное приведение отмапленных из файла страниц к (IndexPageHeader*) c повсеместным применением upper_bound к произвольным итераторам, происхождение которых по коду отследить невозможно.

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

_>>Не имею ничего против любых "защит", встраиваемых в язык/компилятор, при условие, что это не приводит к дополнительному оверхеду. Т.е. если говорить например о классической проблеме опасных указателей из языка C, то на мой вкус решение в виде языка Java плохое, а решение в виде языка Rust хорошее...

S>Увы, с растом не знаком.

Rust даёт даже большие гарантии безопасности работы с памятью (например в области разделения данных между потоками), чем Java или C#, имея при этом нулевой оверхед (как в C и C++ — никаких сборщиков мусора и т.п. ерунды). Ну конечно у всего есть своя цена и в случае Rust'а ею является несколько "зашумлёный" соответствующими синтаксическими конструкциями код и естественно более высокие требования к уровню программистов (надо понимать концепции нескольких видов указателей и их взаимного превращения).

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

S>Брр. Попробую по буквам: в linq так и формируется "соответствующий императивный код". Query comprehension — это всего лишь сахар для построения определённой цепочки вызовов.

Мы же вроде вместе пошагово выяснили, что даже для реализации простейшего двоичного поиска по массиву int'ов тебе потребуется написать код разбора передаваемого тебе дерева предикатов, выполняющийся в рантайме. Какое тут ещё формирование кода компилятором и вообще какая-то эффективность?

S>Нет никакой "невозможности зашить в компилятор" — компилятор С++ прекрасно порождает высокоэффективный код из подобных цепочек вызовов, а компиляторы, которые порождают Execution Plan из SQL Query в современных RDBMS успешно применяют метаданные типа кардинальности связей, ограничения и прочее при выборе стратегий исполнения на лету.


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

_>>Ну так и никто не мешает тебе вставить в своём коде алгоритма поиска соответствующую проверку (типа "if(end(r)-begin(r)<10) ..."), с нужными для твоего алгоритма результатами. И эта проверка тоже не будет нести ни капли оверхеда.

S>А ещё можно просто вручную отсортировать массив констант. Мы же говорим о применении компьютера. Я не собираюсь полагаться на то, что программист записал всё верно, и наша магическая константа везде равна именно 10, а не 010, написанные по ошибке в одном из мест использования. Чтобы "соответствующая проверка" не несла ни капли оверхеда, компилятор должен быть очень умным — в частности, уметь доказывать теоремы для устранения избыточных проверок.
S>При этом для банальных сценариев типа индексации массива в цикле устранение избыточных проверок уже делают все современные JIT-компиляторы — и для Java, и для .Net.

Если у тебя в твоей конкретной задаче есть необходимость раскидать проверки абсолютно везде, то тебе никто не мешает вставить эту проверку в используемую тобой коллекцию (в тот же оператор [], если очень хочется). Ну и в любом случае совершенно непонятно какое это имеет отношения к обсуждаемому вопросу.

_>>А вот тут ты как раз принципиально ошибаешься. Ты путаешь принципиальное отсутствие оверхеда у определённых видов абстракции в определённых языках и работу оптимизатора. В том то и заключается ключевой нюанс, что вышеприведённый код будет идентичен a[10] даже при полностью выключенных опциях оптимизации — это гарантированная особенность реализации, а не надежда на хорошую оптимизацию.

S>Да ничего я не путаю.
S>Во-первых, тождество a[x]==*(a+x) работает только для встроенных массивов.

Ну не только для них, но не суть. У меня то в примере был именно встроенный, не так ли? И утверждение про идентичность относилось именно к этому коду, правильно? Тогда на что интересно было высказано это твоё возражение? ))) Снова эти сомнительные приёмы в дискуссии?

S>Как только в качестве a у нас выступает пользовательский тип, обеспечение эквивалентности операторов [] и + начинает полагаться на совесть программиста. Более того, если отключить прямо все-все оптимизации, то ассемблерный код станет резко другим — ведь нам будет запрещено инлайнить код операторов, которые были определены для класса итератора. Поэтому там будет честный call, вместо ADD 0xA, которого вы наивно ожидаете.


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

S>Во-вторых, такой выбор семантики — плох. То есть одно дело — адресная арифметика, которая заведомо небезопасна (именно поэтому в дотнете она доступа только в unsafe-регионах). А другое дело — индексация массива, которую можно и нужно делать безопасной. Под безопасностью здесь подразумеваются гарантии невылета за пределы "нашей" памяти и отсутствия реинтерпретации данных (type safety).

_>>Как раз последнее в C++ уже давно никто не берётся предсказывать с гарантией, т.к. поведение оптимизатора очень сложно и сильно зависит от окружающих условий (например один и тот же код может илайниться, а может и нет, в зависимости от окружения). А вот гарантию отсутствия оверхеда в описанном случае можно легко дать, т.к. это не оптимизация!
S>Ваше представление об abstraction penalty весьма наивно, простите.

Очень аргументированное утверждение. )))
Re[60]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 03.05.18 23:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Как правило — нет. Я видел всего несколько сценариев, где обыграть MS SQL образца 2005 года было реально (причём я себя считаю очень крутым DBA)
S>Кроме того, пакость — в том, что у человека обычно меньше "знания соответствующих особенностей наборов данных", чем у RDBMS.
S>Если ты спросишь у менеджера, каково характерное количество строк в заказе, то он скорее всего ошибётся на порядок. В любую сторону.
S>Просто потому, что его восприятие искажено. СУБД не подвержено всем вот этим вот observation bias, и точно знает, сколько где там чего.

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

Вообще у нас тут несколько странная ситуация. В большинстве других областей программирования у нас всегда остаётся возможность добраться до низкого уровня. Т.е. развитие шло от некого базиса (исходящего от железа), до высокоуровневых абстракций. Но при этом доступ к низкому уровню всегда сохранялся. А в мире РСУБД у нас в качестве базиса используется уже весьма высокоуровневая абстракция, не позволяющая при надобности добираться до тонкой настройки (всяческие подсказки — это лишь жалкие костыли).

S>Про Hadoop было бы неплохо почитать какие-нибудь success stories, где люди рассказывают в подробностях, что именно заменили, каким способом, и почему.


Так я же уже кидал ссылки прямо в этой темке. Например вот эту https://www.cloudera.com/more/customers/bank-mandiri.html — стало считать 60 минут вместо двух суток. При этом затраты сократились до 1%. Мне кажется вполне очевидная причина... )))

Кстати, там можно в правом нижнем углу нажать на кнопку browse и полюбоваться на ещё сотни подобных историй успеха. Например вот https://www.cloudera.com/more/customers/mbank.html с ещё одно части света или вот с третьей https://www.cloudera.com/more/customers/cartao-elo.html. И везде речь про ускорение, упрощение, удешевление...
Re[16]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.05.18 04:10
Оценка: +1
Здравствуйте, alex_public, Вы писали:

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

S>>Брр. Попробую по буквам: в linq так и формируется "соответствующий императивный код". Query comprehension — это всего лишь сахар для построения определённой цепочки вызовов.

_>Мы же вроде вместе пошагово выяснили, что даже для реализации простейшего двоичного поиска по массиву int'ов тебе потребуется написать код разбора передаваемого тебе дерева предикатов, выполняющийся в рантайме. Какое тут ещё формирование кода компилятором и вообще какая-то эффективность?

Уфф. Тут опять происходит смешивание синтаксиса и реализации. В нынешнем C# — да, так и приходится делать, писать код разборки, выполняющийся в рантайме.
Его компилятор не содержит каких-либо средств, способных превратить where (p.Age >= 21) && (p.Name.BeginsWith("A") в .AgeIndex.Seek(21).Scan().Where(x=>x.Name.BeginsWith("A")).
Это не означает, что таких средств не может быть.
А если мы их применяем, то вместо дерева предикатов мы имеем вполне себе гражданский код, подверженный тому же инлайнингу и оптимизациям, что и аналогичная С++ реализация, выписанная вручную.

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

Вы так говорите, как будто это что-то плохое. Метапрограммирование в С++ работает с начала девяностых; Немерле так и вообще состоит из него чуть менее, чем полностью.
Впрочем, меня не очень беспокоит вопрос применения метапрограммирования в рантайме — более того, я считаю эту тему весьма перспективной. Главное — уметь сохранять результаты.
То есть требовать перекомпиляции на каждую итерацию цикла — это, естественно, бред. Должны быть средства спекулятивной оптимизации — то есть мы проводим разбор дерева, трансформируем там всё, что надо, и прикапываем готовый результат вместе с guard conditions — предположениями, которые мы сделали при генерации. При следующем исполнении мы проходим сразу же по оптимизированному пути, избегая дорогостоящего этапа оптимизации.
Если guard conditions нарушаются — мы проходим по медленному пути. Если guard conditions нарушаются часто — мы выбрасываем оптимизированный код и выполняем оптимизацию заново.
Примерно так работают взрослые системы, рассчитанные на эксплуатацию 24*7.
Для настольного софта скорее всего будет более эффективна популярная ныне тема PGO.

_>Если у тебя в твоей конкретной задаче есть необходимость раскидать проверки абсолютно везде, то тебе никто не мешает вставить эту проверку в используемую тобой коллекцию (в тот же оператор [], если очень хочется). Ну и в любом случае совершенно непонятно какое это имеет отношения к обсуждаемому вопросу.

Прямое. Как только я вставил проверку в оператор [], так он сразу перестал быть эквивалентен *(+), в котором никакой проверки нет.

_>Ну не только для них, но не суть. У меня то в примере был именно встроенный, не так ли?

Нет, у вас был iterator_range().begin(). Наверное, можно при помощи частичной специализации типизировать этот метод в int*, но в реальном коде (длиннее, чем hello world) гарантировать это довольно-таки затруднительно.
Потому что вы смотрите на строчку кода, которая выводит тип из окружения (auto it=begin(r)), и для получения точной информации о том, как устроен этот тип, вам надо определить тип r, просмотреть весь код begin, и так по цепочке. И завтра это может измениться, потому что ваш коллега закоммитил в репозиторий изменение, перейдя от int[] к vector<int> или ещё к чему-то.

_>Да, в случае нетривиальной коллекции и отключённой оптимизации у нас будет call, а не обращение по адресу. Более того, это возможно и в случае включённой оптимизации, если код соответствующих операторов очень тяжёлый и оптимизатор решит что его невыгодно инлайнить. Но к обсуждаемому вопросу это отношения не имеет, т.к. моё утверждение было о "нулевом оверхеде", а не о какой-то конкретной ассемблерной инструкции. Ведь при использование нетривиальной коллекции с выключенной оптимизацией у тебя и при вызове a[] будет call.

В таком случае разговор об оверхеде не имеет смысла.
Давайте вообще реализуем коллекцию в виде односвязного списка из пар {key, value}, оператор [] у нас будет работать как {for(i=head;i!=null;i=i.next} if (i->key == key) return i->value; throw new index_out_of_range()}.
И оператор + мы определим точно так же — даже не будем вызывать уже готовый [], чтобы избежать лишнего потенциального вызова.
"Оверхед", конечно же, будет по-прежнему нулевым. При этом код будет, мягко говоря, не вполне оптимальным в среднем случае.
Поэтому я термин "оверхед" не люблю, и предпочитаю пользоваться терминами performance и abstraction penalty.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[61]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.05.18 04:23
Оценка:
Здравствуйте, alex_public, Вы писали:


S>>Про Hadoop было бы неплохо почитать какие-нибудь success stories, где люди рассказывают в подробностях, что именно заменили, каким способом, и почему.


_>Так я же уже кидал ссылки прямо в этой темке. Например вот эту https://www.cloudera.com/more/customers/bank-mandiri.html — стало считать 60 минут вместо двух суток. При этом затраты сократились до 1%. Мне кажется вполне очевидная причина... )))

(facepalm). Я выделил важное. Мне интересны технические детали. А вот этот вот маркетинговый булшит про удешевление в 100 и ускорение в 48 раз мне неинтересен.
Потому, что там за кадром может быть всё, что угодно. Например, у нас сейчас по одному из продуктов "приготовить данные" занимает даже не 2 дня, а иногда и 2 недели.
При этом СУБД там работает секунд 10-20. Всё остальное время — следствие криворукой реализации. Потому, что именно этот продукт не помечает ордера кодом продукта (из-за длинной цепочки причин — там пришлось идти на компромиссы из-за десятков противоречивых ограничений задействованных систем), поэтому встроенные отчёты его не покрывают. Для него навелосипедили SQL кверю с оператором like для "угадывания" нужных данных, которую надо гонять по production базе.
При этом, естественно, права доступа на исполнение такой квери ограничены. И права на то, чтобы выдать задание уполномоченному администратору на исполнение такой квери тоже ограничены.
А потом результат этого запроса надо обрабатывать напильником в екселе, потому что like не всё угадывает правильно, и потому что данные приезжают во всех валютах сразу, и надо их конвертировать в USD с учётом даты продажи и официального курса компании на дату ордера.
Этим занимается специально уполномоченный рукожоп из отдела accounts receivable, у которого своё расписание и свои приоритеты.
Я почти уверен, что можно заменить всю эту кунсткамеру любым OLAP решением, которое позволит людям вроде меня задавать свои выборки данных, и сократить время генерации до 15 минут.
При этом с инженерной точки зрения это будет явным ухудшением — вместо 20 секунд мы гоняем железку 15 минут — а менеджмент отрапортует о титанических свершениях в духе процитированной вами статьи. Потому что менеджмент не в курсе, кто и сколько там под капотом работает.

Продавать булшит я и сам умею — профессиональные навыки-с. Интересно не купить булшит — то есть посмотреть, в чём была проблема, какие были меры предприняты, как они помогли или не помогли.
Вот у нас тут по соседству участник задавал вопрос про приручение SQL — у него там самописанное на java решение работает в 10 раз быстрее.
Я, к сожалению, не смог выяснить достаточно подробностей для того, чтобы прикинуть query plan и возможности по его оптимизации. Но по крайней мере технически это интересно.

_>Кстати, там можно в правом нижнем углу нажать на кнопку browse и полюбоваться на ещё сотни подобных историй успеха. Например вот https://www.cloudera.com/more/customers/mbank.html с ещё одно части света или вот с третьей https://www.cloudera.com/more/customers/cartao-elo.html. И везде речь про ускорение, упрощение, удешевление...
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[62]: В России опять напишут новый объектно-ориентированны
От: Gt_  
Дата: 04.05.18 09:30
Оценка: +1
_>>Так я же уже кидал ссылки прямо в этой темке. Например вот эту https://www.cloudera.com/more/customers/bank-mandiri.html — стало считать 60 минут вместо двух суток. При этом затраты сократились до 1%. Мне кажется вполне очевидная причина... )))
S>(facepalm). Я выделил важное. Мне интересны технические детали. А вот этот вот маркетинговый булшит про удешевление в 100 и ускорение в 48 раз мне неинтересен.
S>Потому, что там за кадром может быть всё, что угодно. Например, у нас сейчас по одному из продуктов "приготовить данные" занимает даже не 2 дня, а иногда и 2 недели.


не верный подход. потому что именно цена там одно из самых интересных. у нас было несколько региональных dwh систем на оракле их объединили в одно хранилище на хадуп, порядка 300 ядер в кластере. лицензировать сравнимое число ядер под EE оракл + RAC + партишенинг X 2 из-за стендбая в принципе не реально. плюс железо, понадобятся дорогие сториджи с дорогими ентепрайз дисками.
что касается приготовить, то да, зачастую там выходит быстрее. в первую очередь от того, что в том же бюджете много больше железа. дальше там подходы к "готовке" другие, ну и за счет параллелизма. рдбмс зачастую читает таблицу всего лишь несколькими потоками, примерно столько, сколько партиций в таблице, пишет в темп хеш, потом в одном потоке читает этот же хеш, hash-join считай один поток. зачастую хадуп за это время успевает поднять все хранилище, со всеми "таблицами", с их историей за все времена и записать результат. да, работы выполнено много больше, данных перелопачено много больше, но и результат много быстрее, потому этим занимались сотни ядер с гораздо большей степенью параллелизма.
Re[63]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.05.18 09:54
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>не верный подход. потому что именно цена там одно из самых интересных. у нас было несколько региональных dwh систем на оракле их объединили в одно хранилище на хадуп, порядка 300 ядер в кластере. лицензировать сравнимое число ядер под EE оракл + RAC + партишенинг X 2 из-за стендбая в принципе не реально. плюс железо, понадобятся дорогие сториджи с дорогими ентепрайз дисками.

Gt_>что касается приготовить, то да, зачастую там выходит быстрее. в первую очередь от того, что в том же бюджете много больше железа. дальше там подходы к "готовке" другие, ну и за счет параллелизма. рдбмс зачастую читает таблицу всего лишь несколькими потоками, примерно столько, сколько партиций в таблице, пишет в темп хеш, потом в одном потоке читает этот же хеш, hash-join считай один поток. зачастую хадуп за это время успевает поднять все хранилище, со всеми "таблицами", с их историей за все времена и записать результат. да, работы выполнено много больше, данных перелопачено много больше, но и результат много быстрее, потому этим занимались сотни ядер с гораздо большей степенью параллелизма.
Непонятно, каким макаром хадуп добивается "параллелизма в чтении". Пока что у всех известных мне дисков линейное чтение (то есть в один поток) рвёт многопотоковое чтение по скорости — только в путь.
Вот, тут недавно обсуждали современные SSD — там деградация при "многопотоковом" чтении (при много = 64..128) не столь существенна, как для HDD, но всё же тоже — деградация, а вовсе не ускорение.
Если речь про параллелизм на разных машинах с независимыми стораджами — ну, RDBMS так тоже умеют. Не уверен насчёт прямо 300 машин, но партишнинг тоже существует, и агрегация выполняется везде одновременно, и уже потом сливается в финальный результат.

Впрочем, я от темы-то отвлёкся — DWH это достаточно специфическая отрасль, для неё RDBMS не обязана быть прямо лучшим выбором. Интересно было бы посмотреть на OLTP.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[59]: В России опять напишут новый объектно-ориентированны
От: MadHuman Россия  
Дата: 04.05.18 11:08
Оценка:
Здравствуйте, alex_public, Вы писали:

_>>>У linq есть множество очевидных недостатков. Причём как концептуальных (как раз связанных с моделью SQL),

MH>>можете назвать самые важные концептуальные?

_>Тут надо разделить недостатки в работе с коллекциями и в работе с СУБД. Хотя уже собственно в этом наблюдается один из важнейших концептуальных недостатков — попытка объединить универсальным интерфейсом настолько разные вещи. Но это так сказать общие слова, а нам нужны детали. Значит по пунктам:


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

спорное утверждение. если речь идёт о выборе парадигмы для работы с реляционными данными, то я бы в большинстве случаев выбирал функциональные подходы.
но думаю нам тут не стоит углубляться в функциональный vs императивный — все кому вопрос интересен в курсе плюсов/минусов в каждом подходе.

_> Более того, используемая для работы с коллекциями реализация (IEnumerable) является даже более ограниченной (только последовательный доступ), чем классический SQL, для которого в СУБД происходит интерпретация в императивный код.

это ещё более спорное утверждение (если рассматривать linq именно как средство для работы с РСУБД). в linq реализация IEnumerable не используется. упрощённо можно считать, что IEnumerable<T> интерпретируется как источник данных (записей класса T), таблица например.


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


да, РСУБД в рамках своей реализации sql поддерживают императивные возможности, но когда дело доходит до декларации/выполнения запроса к данным (именно sql) — сам запрос остается чисто функциональным (или может термин декларативный — тут больше подойдёт).
но и linq ведь сделан в рамках языка общего назначения, а значит при построении linq-запросов, итерации по результатам можно использовать императивные приёмы, причём возможностей будет заметно больше. будет разница в том, что в 1-м случае это выполняется на сервере СУБД, во 2-м — на клиенте, но это IMHO не концептуальный недостаток, просто стоит учитывать.

_>Что уж тут говорить о поддержке наиболее активно развиваемых сейчас распределённых вычислений (СУБД на базе hadoop и т.п.), в которых уже даже MapReduce становится устаревшим (см. Spark).

разве там используется какая-то другая концептуальная модель работы с данными, и не разновидность sql?
полагаю что не другая, а значит это будет лиш вопрос реализации linq-провайдера к этой базе.


_>Linq автоматически наследует все концептуальные проблемы SQL.

ну раз уж упомянули про "концептуальные проблемы SQL", то было бы интересно услышать ваше видение их...
Re[64]: В России опять напишут новый объектно-ориентированны
От: Gt_  
Дата: 04.05.18 13:15
Оценка:
S>Непонятно, каким макаром хадуп добивается "параллелизма в чтении". Пока что у всех известных мне дисков линейное чтение (то есть в один поток) рвёт многопотоковое чтение по скорости — только в путь.
S>Вот, тут недавно обсуждали современные SSD — там деградация при "многопотоковом" чтении (при много = 64..128) не столь существенна, как для HDD, но всё же тоже — деградация, а вовсе не ускорение.
S>Если речь про параллелизм на разных машинах с независимыми стораджами — ну, RDBMS так тоже умеют. Не уверен насчёт прямо 300 машин, но партишнинг тоже существует, и агрегация выполняется везде одновременно, и уже потом сливается в финальный результат.

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

S>Впрочем, я от темы-то отвлёкся — DWH это достаточно специфическая отрасль, для неё RDBMS не обязана быть прямо лучшим выбором. Интересно было бы посмотреть на OLTP.


олтп не видел, обычно там касандры, монгодб ... на хадупе самое близкое к олтп бывает строят связку kafka->spark->hadoop. в кафку какой-нибудь IoT льет мульены сообщений, спарк обрабатывает на лету и записывает на хадуповскую файловую систему hdfs

Gt_
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.