Здравствуйте, Ikemefula, Вы писали:
_>>Ещё раз: хранимые процедуры — это не SQL. Это процедурный (императивный) язык, в то время как SQL является полностью декларативным языком. I>Имеем следующую цитату "SQL тоже позволяет произвольный императивный код, глобальные переменные " I> Плюрализм, однако. I>Как тебя понимать, императивные расширения SQL это SQL или нет ? В одном месте ты пишешь, что да, в другом — что нет.
Мдаа, ну такого наглого цитирования с полной заменой смысла на обратный я вообще ещё не встречал на форуме. Я вот даже не пойму на что ты рассчитывал, написав такое, что я просто поленюсь ответить или что? )))
) заканчивалась знаком вопроса (который ты стёр) и соответственно являлась не утверждением, а вопросом. Более того, это был риторический вопрос подразумевающий отрицательный ответ, хотя это уже даже не важно.
Ужас какой-то, некоторые адекватные в прошлом коллеги по форуму становятся в последнее время совсем странными. Похоже уже скоро надо будет чёрные списки заводить, чтобы не тратить время на подобных.
Re[42]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>>О, я смотрю от изначального тезиса, что "у MySQL проблемы с consistency и availability" мы незаметно попытались перейти к новому тезису, что "у MySQL были проблемы с consistency и availability до определённой версии". IB>О, я смотрю проблемы не только с написанием, но еще и с чтением? =) IB>С процитирую еще раз, мне не сложно: IB>such as MySQL – were originally designed with only consistency and availability in mind IB>Как видно по исходной цитате, речь изначально шла о том, для чего именно был задизайнен MySQL, а не о том, что он умеет сейчас. Так вот уж точно не для Consistency и availability, так как их там даже близко не было. IB>Правильный ответ (уловите иронию) для создания более эффективного и удобного API к ISAM базам, и таким API явился SQL.
Смотрим сюда: https://ru.wikipedia.org/wiki/InnoDB и видим что поддержка появилась в версии 3.23. А с учётом того, что первая публичная версия имела номер 3.21, то мне не кажется, что они реально сосредотачивались на поддержке только одного движка (ISAM)... )))
_>> А можно теперь озвучить в какому году появилась та версия (в которой добавили InnoDB), начиная с которой проблем нет? IB>По дефолту? Кажется, середина 16-го года.
И снова у тебя пробелы в знаниях. Даже если говорить о дефолте, то в соответствие со ссылкой выше это произошло в версии mysql 5.5 (которая вышла в 2010-м году). Ну а если отвечать на заданный мною вопрос (а не тот, который ты придумал сам для себя), то опять же в соответствие со ссылкой выше это произошло в версии 3.23 (2001-ый год).
_>> И это логично, т.к. далеко не для всех БД это полезно. IB>Ну так и я о том же, есть ОЛАП, есть BigData, где традиционная реляционка работает только до определенных пределов. Собственно об этом я и написал еще три сообщения назад.
Несколько сообщений назад ты как раз писал о том, что эти направления не особо растут. Собственно для опровержения этого твоего утверждения и я приводил ссылку на попавшуюся под руку статью.
_>>Однако ты тут утверждал, что подобных переходов никто не делает в принципе. IB>Цитату можно? Где прям в принципе?
Да их много было. Например такая:
Иными словами, noSQL — это не замена SQL, а новый инструмент для нового сценария (Big Data).
или такая:
Попытались было впихнуть вместо SQL-я, но что-то пошло не так.
Как видишь, на практике вполне себе заменяют реляционные БД на различные nosql решения, в том числе и даже в таких консервативных местах, как банки. Естественно заменяют не все реляционные БД, а только подходящие для этого. Но сам факт замены это не отменяет...
Re[5]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Ммм, при слове escape-analysis у меня появляется ассоциация исключительно с соответствующим механизмом в Java, который работает как раз не на уровне компилятора, а на уровне виртуальной машины (причём ещё и на вероятностных принципах, анализируя рантаймовые параметры). Если ты имел в виду что-то другое (статическое, на этапе компиляции), то значит у нас тут просто небольшое рассогласование в терминологии. S>Ок, поясню: размещение в куче позволяет объекту пережить тот стек-фрейм, в котором он был создан. S>Это необходимо, если ссылка на этот объект покидает этот стек-фрейм. Если же время жизни всех ссылок на этот объект ограничено временем жизни стек-фрейма, то можно разместить этот объект на стеке прозрачно для всего остального кода. S>Проверка этой гипотезы и называется escape analysis: мы смотрим, не "сбегает" ли ссылка. Кто это делает — компилятор или среда — неважно. Механизм — один и тот же.
Ну пока что в .net это не делает никто, а в Java это делает среда, причём довольно специфическим образом (см. ниже).
S>В управляемой среде компилятор может отловить только самые очевидные случаи. Инлайнинг и прочий хардкор, который может позволить уточнить результаты escape-analysis, производится на уровне JIT.
Инлайнинг тоже желательно делать не jit, ну да ладно.
S>Насколько я знаю, никаких вероятностей в Java нету — ведь если мы с вероятностью 1% ошибаемся, то один раз из ста у нас наружу уходит ссылка на разрушенный объект.
Под вероятностью я имел в виду, что виртуальная машина java переносит на стек далеко не все переменные, которые в теории можно было бы перенести.
_>>Ты действительно хочешь сказать, что в программирование не встречается задач, где входные данные уже гарантированно отсортированы? ) S>Гарантии может дать только статически верифицируемый код. Поэтому наиболее эффективный способ — это ввести тип SortedList, который будет гарантировать наличие сортировки независимо от количества коммитов в репозиторий, прошедших со дня первоначальной сборки.
Мммм, уточни о чём ты.
Если ты про что-то типа:
typdef vector<int> sorted_array;
то с подобным использованием преимуществ статической типизации как бы никто и не спорит (просто лень было вставлять такие незначительные и непринципиальные детали в нашу беседу)
Если же ты про специализированный контейнер, который занимается поддержанием себя в отсортированном состояние (т.е. загрузка в него данных приводит к обязательному исполнению функции сортировки), то это очевидно очень плохая идея с точки зрения производительности при условие уже отсортированных входных данных.
S>И тут у нас всё точно так же: важно предотвратить нарушение инвариантов. По-хорошему, конструктор обязан удостовериться за O(N) что массив и правда отсортирован.
Так и представил себе, что все СУБД при старте говорят что-то вроде: мы тут пока пересчитаем все индексы ко всем БД, а то мало ли...
_>>Не вижу никакой принципиальной разницы между случаем отсортированного int[] и myfields[], отсортированного по какому-то из полей структуры myfields. И в том и в другом случае тебе всё равно приходится руками писать тот же самый императивный код в своей реализации where для данного типа. S>Нет. Where пишется один раз для SortedList<T>, также, как и i4o, который уже написан. Там внутри — анализ предиката в поисках сравнений ключевого атрибута с параметром, перестроение предиката на "индексную" и "остаточную" части, и потом выполнение кода. Никакой специфики для пользовательского типа там нет.
Оу. Даже если забыть о потерях производительности (на этот самый анализ — он же в рантайме у linq делается, не так ли?), то даже само написание подобной нетривиальной функции будет намного дольше, чем написание десятков частных случаев (в виде императивного кода).
Кстати, подскажешь как вообще выглядит объявление кастомного where у linq? А то я тут ради интереса решил загуглить (смотрел на linq binary search) как оно выглядит и что-то натыкался кругом на ответы, что это невозможно. Ну видимо народ на SO и т.п. местах просто не в курсе как правильно это делать. Подскажешь как такое задаётся?
_>>С чего это переписывать полностью императивный код при правке предиката? Или ты думаешь он там какой-то ассемблерной магией задаётся, а не той же самой банальной строчкой с условием? ) S>Может, я и правда чего-то не понимаю? S>Давайте в студию пример императивного кода, который заменяет вот такой вот примитивный query comprehension: S>
S>var t = from p in persons where p.Age >= 18 && p.Age <= 65 && p.Name.StartsWith("K") select p
S>
S>Предположим, что persons — массив, который уже отсортирован по Age.
Ну скажем на C++ это будет выглядеть так:
auto t=persons|upper_bound(persons, 18, &person.age)|lower_bound(persons, 65, &person.age)|filter([](person& p){return p.Name.StartsWith("K");});
Однако это легко можно переписать на любом другом языке, не только без ranges, но даже и без итераторов/указателей. Как-нибудь в таком роде (псевдокод):
b=0
e=persons_length
b=upper_bound(persons, b, e, p=>p.age>18)
е=lower_bound(persons, b, e, p=>p.age<65)
t=filter(persons, b, e, p=>p.Name.StartsWith("K"))
S>Как изменится код, если отсортировать массив по Name? S>Как изменится код, если отсортировать массив сначала по Name, потом по Age? S>Как изменится код, если отсортировать массив сначала по Age, потом по Name?
Я думаю ты и сам видишь, как элементарно меняется порядок нужных операций в моём примере кода.
Re[43]: В России опять напишут новый объектно-ориентированны
) заканчивалась знаком вопроса (который ты стёр) и соответственно являлась не утверждением, а вопросом. Более того, это был риторический вопрос подразумевающий отрицательный ответ, хотя это уже даже не важно.
Значит тебе стоит писать более внятно. Судя по форуму, другие поняли точно так же.
Re[6]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Инлайнинг тоже желательно делать не jit, ну да ладно.
C инлайнингом в момент компиляции есть несколько возможных граблей. Простейшие грабли — мы делаем вызов из другой сборки; между компиляцией и исполнением происходит минорный патч вызываемой сборки — в итоге мы "инлайним" совсем не ту версию кода, что содержится в вызываемом коде. _>Под вероятностью я имел в виду, что виртуальная машина java переносит на стек далеко не все переменные, которые в теории можно было бы перенести.
S>>Гарантии может дать только статически верифицируемый код. Поэтому наиболее эффективный способ — это ввести тип SortedList, который будет гарантировать наличие сортировки независимо от количества коммитов в репозиторий, прошедших со дня первоначальной сборки. _>Мммм, уточни о чём ты.
_>Если ты про что-то типа: _>
_>typdef vector<int> sorted_array;
_>
_>то с подобным использованием преимуществ статической типизации как бы никто и не спорит (просто лень было вставлять такие незначительные и непринципиальные детали в нашу беседу)
Нет. Я о том, что должно быть — вот так:
public class SortedList: IEnumerable<int> // для упрощения примера кода - в реальности мы говорим о дженерик-классе
{
public SortedList(int[] alreadySorted)
{
_array = alreadySorted;
if(alreadySorted.Length == 0);
return;
var prev = alreadySorted[0];
for(var i=1; i<alreadySorted.Length; i++)
if (alreadySorted[i]>prev)
throw new ArgumentException("array isn't sorted!");
else
prev=alreadySorted[i];
}
}
Тайпдеф нас не спасёт — я же привёл пример кода. Вам повезло — вы сразу же заметили ошибку.
В жизни бывает не так — кто-то где-то сформировал список, кто-то в другом месте его принял. Всё отладили, убедились, запустили в эксплуатацию. Через два года кто-то третий в третьем месте вставил невинную штуку по добавлению элемента в начало списка. И это даже почти ничего не ломает, потому что чаще всего вставляемое значение меньше или равно минимуму.
А иногда, при опредедённой фазе луны, это значение внезапно больше минимума, и массив уже не удовлетворяет ожидаемому инварианту. Наивный код вырезания сплайса вырезает не то, чего ожидалось, и разработчики проводят недели без сна, пытаясь понять, как такое вообще могло получиться, и почему эта штука иногда внезапно делает не то.
_>Если же ты про специализированный контейнер, который занимается поддержанием себя в отсортированном состояние (т.е. загрузка в него данных приводит к обязательному исполнению функции сортировки), то это очевидно очень плохая идея с точки зрения производительности при условие уже отсортированных входных данных.
Можно и без сортировки — я показал как. _>Так и представил себе, что все СУБД при старте говорят что-то вроде: мы тут пока пересчитаем все индексы ко всем БД, а то мало ли...
Так и происходит. Только не при старте, а при загрузке данных в СУБД: ни одна из них не собирается поверить вам на слово и разрешить прямую вставку в индекс. Только в исходные данные — а индексы она построит сама. _>>>Не вижу никакой принципиальной разницы между случаем отсортированного int[] и myfields[], отсортированного по какому-то из полей структуры myfields. И в том и в другом случае тебе всё равно приходится руками писать тот же самый императивный код в своей реализации where для данного типа. _>Оу. Даже если забыть о потерях производительности (на этот самый анализ — он же в рантайме у linq делается, не так ли?), то даже само написание подобной нетривиальной функции будет намного дольше, чем написание десятков частных случаев (в виде императивного кода).
Десятков — да. А тысяч — нет.
_>Кстати, подскажешь как вообще выглядит объявление кастомного where у linq? А то я тут ради интереса решил загуглить (смотрел на linq binary search) как оно выглядит и что-то натыкался кругом на ответы, что это невозможно. Ну видимо народ на SO и т.п. местах просто не в курсе как правильно это делать. Подскажешь как такое задаётся?
Вот так и задаётся. Либо
public class SortedList
{
...
public SortedList Where(Func<int, bool> predicate)
{
...
}
...
}
либо
public static class SortedListHelper
{
...
public SortedList Where(this SortedList list, Func<int, bool> predicate)
{
...
}
...
}
_>>>С чего это переписывать полностью императивный код при правке предиката? Или ты думаешь он там какой-то ассемблерной магией задаётся, а не той же самой банальной строчкой с условием? ) S>>Может, я и правда чего-то не понимаю? S>>Давайте в студию пример императивного кода, который заменяет вот такой вот примитивный query comprehension: S>>
S>>var t = from p in persons where p.Age >= 18 && p.Age <= 65 && p.Name.StartsWith("K") select p
S>>
S>>Предположим, что persons — массив, который уже отсортирован по Age.
_>Ну скажем на C++ это будет выглядеть так: _>
_>Однако это легко можно переписать на любом другом языке, не только без ranges, но даже и без итераторов/указателей. Как-нибудь в таком роде (псевдокод): _>
_>b=0
_>e=persons_length
_>b=upper_bound(persons, b, e, p=>p.age>18)
_>е=lower_bound(persons, b, e, p=>p.age<65)
_>t=filter(persons, b, e, p=>p.Name.StartsWith("K"))
_>
S>>Как изменится код, если отсортировать массив по Name? S>>Как изменится код, если отсортировать массив сначала по Name, потом по Age? S>>Как изменится код, если отсортировать массив сначала по Age, потом по Name?
_>Я думаю ты и сам видишь, как элементарно меняется порядок нужных операций в моём примере кода.
Ну, пока не вижу, потому что не очень понимаю семантику upper_bound. В частности, непонятно, как она себя поведёт, если мы внутри поменяем порядок сортировки — она просто упадёт, вернёт некорректный результат, или вернёт корректный результат за O(N) вместо O(logN)?
Не очень понятно применение операции | к итераторам. То, что написано в псевдокоде, это и есть linq за вычетом query comprehensions.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Инлайнинг тоже желательно делать не jit, ну да ладно. S>C инлайнингом в момент компиляции есть несколько возможных граблей. Простейшие грабли — мы делаем вызов из другой сборки; между компиляцией и исполнением происходит минорный патч вызываемой сборки — в итоге мы "инлайним" совсем не ту версию кода, что содержится в вызываемом коде.
Инлайн динамически загружаемых библиотек действительно стоит отдавать среде исполнения. Но это уже так сказать уже последний штрих на картину, о котором .net'у пока думать несвоевременно. Ему бы достичь уровня обычного нативного кода (в котором кстати инлайн динамических библиотек вообще не используется), а потом уже можно и о таком думать.
_>>Если ты про что-то типа: _>>
_>>typdef vector<int> sorted_array;
_>>
_>>то с подобным использованием преимуществ статической типизации как бы никто и не спорит (просто лень было вставлять такие незначительные и непринципиальные детали в нашу беседу) S>Нет. Я о том, что должно быть — вот так: S>
S>public class SortedList: IEnumerable<int> // для упрощения примера кода - в реальности мы говорим о дженерик-классе
S>{
S> public SortedList(int[] alreadySorted)
S> {
S> _array = alreadySorted;
S> if(alreadySorted.Length == 0);
S> return;
S> var prev = alreadySorted[0];
S> for(var i=1; i<alreadySorted.Length; i++)
S> if (alreadySorted[i]>prev)
S> throw new ArgumentException("array isn't sorted!");
S> else
S> prev=alreadySorted[i];
S> }
S>}
S>
S>Тайпдеф нас не спасёт — я же привёл пример кода. Вам повезло — вы сразу же заметили ошибку. S>В жизни бывает не так — кто-то где-то сформировал список, кто-то в другом месте его принял. Всё отладили, убедились, запустили в эксплуатацию. Через два года кто-то третий в третьем месте вставил невинную штуку по добавлению элемента в начало списка. И это даже почти ничего не ломает, потому что чаще всего вставляемое значение меньше или равно минимуму. S>А иногда, при опредедённой фазе луны, это значение внезапно больше минимума, и массив уже не удовлетворяет ожидаемому инварианту. Наивный код вырезания сплайса вырезает не то, чего ожидалось, и разработчики проводят недели без сна, пытаясь понять, как такое вообще могло получиться, и почему эта штука иногда внезапно делает не то.
Эм, ты серьёзно предлагаешь обсуждать код, нарушающий задокументированный инвариант? ) И вместо использования юнит-тестов, предлагаешь замедлить код рантаймовой проверкой? )))
_>>Если же ты про специализированный контейнер, который занимается поддержанием себя в отсортированном состояние (т.е. загрузка в него данных приводит к обязательному исполнению функции сортировки), то это очевидно очень плохая идея с точки зрения производительности при условие уже отсортированных входных данных. S>Можно и без сортировки — я показал как.
Ну это же по сути аналог typedef, не так ли?
_>>Так и представил себе, что все СУБД при старте говорят что-то вроде: мы тут пока пересчитаем все индексы ко всем БД, а то мало ли... S>Так и происходит. Только не при старте, а при загрузке данных в СУБД: ни одна из них не собирается поверить вам на слово и разрешить прямую вставку в индекс. Только в исходные данные — а индексы она построит сама.
Так при старте СУБД все файлы (пускай и записанные ею в предыдущей сессии) являются входными данными. Так что тогда полагается пересчитать все индексы при старте, а то мало ли кто их там правил, пока СУБД была отключена...
_>>Кстати, подскажешь как вообще выглядит объявление кастомного where у linq? А то я тут ради интереса решил загуглить (смотрел на linq binary search) как оно выглядит и что-то натыкался кругом на ответы, что это невозможно. Ну видимо народ на SO и т.п. местах просто не в курсе как правильно это делать. Подскажешь как такое задаётся? S>Вот так и задаётся. Либо S>
Ага, т.е. достаточно объявить функцию Where у класса и она будет всегда использоваться? Выглядит неплохо. Непонятно тогда почему на SO все писали, что мол двоичный поиск невозможно реализовать, т.к. IEnumerable не поддерживает произвольный доступ. Раз у нас есть доступ к "this" оригинального типа, то естественно никаких проблем не видно.
А как предполагается делать анализ нашего предиката? Нам же при двоичном поиске не подходит просто запуск Func для каждого элемента...
_>>Ну скажем на C++ это будет выглядеть так: _>>
_>>Однако это легко можно переписать на любом другом языке, не только без ranges, но даже и без итераторов/указателей. Как-нибудь в таком роде (псевдокод): _>>
_>>b=0
_>>e=persons_length
_>>b=upper_bound(persons, b, e, p=>p.age>18)
_>>е=lower_bound(persons, b, e, p=>p.age<65)
_>>t=filter(persons, b, e, p=>p.Name.StartsWith("K"))
_>>
S>>>Как изменится код, если отсортировать массив по Name? S>>>Как изменится код, если отсортировать массив сначала по Name, потом по Age? S>>>Как изменится код, если отсортировать массив сначала по Age, потом по Name? _>>Я думаю ты и сам видишь, как элементарно меняется порядок нужных операций в моём примере кода. S>Ну, пока не вижу, потому что не очень понимаю семантику upper_bound. В частности, непонятно, как она себя поведёт, если мы внутри поменяем порядок сортировки — она просто упадёт, вернёт некорректный результат, или вернёт корректный результат за O(N) вместо O(logN)?
Способ обхода зависит (естественно это всё определяется на этапе компиляции) от типа входного итератора. Если тот относится к концепту RandomAccessIterator, то будет O(logN), а иначе O(N).
S>Не очень понятно применение операции | к итераторам.
Потому что это не итераторы, а диапазоны (ranges), которые по сути представляют из себя пару итераторов (тем самым однозначно задавая любую коллекцию или её часть или некое её отображение или вообще генератор). Вот, можешь глянуть что это такое в деталях: https://www.youtube.com/watch?v=LNXkPh3Z418 — довольно интересно видео, охватывающее сразу множество вопросов. И да, в видео это обсуждается как некая новинка, но это только в контексте добавления данной функциональности в стандарт языка. А так то оно уже больше десятилетия доступно в Boost'е.
S>То, что написано в псевдокоде, это и есть linq за вычетом query comprehensions.
Нет, на псевдокоде задана как раз эмуляция диапазонов для случая простейшего массива (задание двух индексов + самого массива равносильны заданию двух итераторов в диапазоне). И это намного удобнее и эффективнее IEnumerable .
Re[8]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Эм, ты серьёзно предлагаешь обсуждать код, нарушающий задокументированный инвариант? ) И вместо использования юнит-тестов, предлагаешь замедлить код рантаймовой проверкой? )))
Я, наверное, не вполне понимаю, о каких юнит тестах идёт речь.
Если юнит хочет возвращать отсортированный массив — пусть возвращает SortedList. Это позволит нам устранить лишние проверки, и заменить юнит-тестирование просто компиляцией.
_>Ну это же по сути аналог typedef, не так ли?
По сути — да. _>Так при старте СУБД все файлы (пускай и записанные ею в предыдущей сессии) являются входными данными. Так что тогда полагается пересчитать все индексы при старте, а то мало ли кто их там правил, пока СУБД была отключена...
Ну, вообще многие СУБД хранят и контрольные суммы — на случай, если кто-то вмешался в данные, "пока СУБД была отключена", и при расхождениях начинают восстанавливать данные.
Но я бы провёл некоторую границу между случайным изменением вполне рабочего кода, и злонамеренным вмешательством в файл.
Если вы пишете систему, в которой помимо СУБД в файл вмешивается кто-то ещё, и это происходит на регулярной основе, то я бы точно так же рекомендовал выполнять как минимум валидацию индексов при старте.
_>Ага, т.е. достаточно объявить функцию Where у класса и она будет всегда использоваться? Выглядит неплохо. Непонятно тогда почему на SO все писали, что мол двоичный поиск невозможно реализовать, т.к. IEnumerable не поддерживает произвольный доступ. Раз у нас есть доступ к "this" оригинального типа, то естественно никаких проблем не видно.
Нельзя сделать двоичный поиск для IEnumerable.
Можно — для своего SortedArray. Можно рискнуть и для банального T[], если сильно хочется приключений.
_>А как предполагается делать анализ нашего предиката? Нам же при двоичном поиске не подходит просто запуск Func для каждого элемента...
Вкратце — сигнатура метода будет немножко другой:
public SortedList Where(this SortedList list, Expression<Func<int, bool>> predicateExpr)
Нам передаётся вместо делегата его AST-представление, которое мы анализируем. Точно так же, как это делает linq2sql или linq2db.
Подробности можно просто посмотреть в исходниках i4o.
_>Способ обхода зависит (естественно это всё определяется на этапе компиляции) от типа входного итератора. Если тот относится к концепту RandomAccessIterator, то будет O(logN), а иначе O(N).
RandomAccessIterator не имеет никакого отношения к отсортированности списка.
_>Потому что это не итераторы, а диапазоны (ranges), которые по сути представляют из себя пару итераторов (тем самым однозначно задавая любую коллекцию или её часть или некое её отображение или вообще генератор). Вот, можешь глянуть что это такое в деталях: https://www.youtube.com/watch?v=LNXkPh3Z418 — довольно интересно видео, охватывающее сразу множество вопросов. И да, в видео это обсуждается как некая новинка, но это только в контексте добавления данной функциональности в стандарт языка. А так то оно уже больше десятилетия доступно в Boost'е.
S>>То, что написано в псевдокоде, это и есть linq за вычетом query comprehensions. _>Нет, на псевдокоде задана как раз эмуляция диапазонов для случая простейшего массива (задание двух индексов + самого массива равносильны заданию двух итераторов в диапазоне). И это намного удобнее и эффективнее IEnumerable .
Linq не имеет к IEnumerable почти никакого отношения. Кроме того, что есть специальный класс Enumerable, в котором определены методы-расширения, позволяющие использовать IEnumerable в query comprehensions.
Мы можем завести свой тип Range, определив его подходящим для нас образом, и полностью заменить всю математику linq.
В том числе мы можем сделать отложенное вычисление, построив полное-полное дерево выражений на весь конвеер, сгенерировать для него dynamicMethod и вручную выполнить инлайнинг произвольной агрессивности.
Основная беда — в том, что сейчас компилятор с какого-то бодуна строит Expression<> динамически на каждом вызове, вместо однократной инициализации. Из-за этого невозможно прозрачно для пользователя кэшировать результат анализа Expression Tree — его надо прикапывать вручную.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[43]: В России опять напишут новый объектно-ориентированны
_>Смотрим сюда: https://ru.wikipedia.org/wiki/InnoDB и видим что поддержка появилась в версии 3.23. А с учётом того, что первая публичная версия имела номер 3.21, то мне не кажется, что они реально сосредотачивались на поддержке только одного движка (ISAM)... )))
А если смотреть не на номера версий, а на года (начало 90-х ISAM и начало двухтысячных InnoDB), то становится очевидно, что ничего кроме ISAM у них и в мыслях не было.
У ребят была конкретная цель, о которой они не стесняясь написали в той же вики — более производительный и удобный API к ISAM. Так что не надо презерватив на глобус натягивать и манипулировать номерами версий. =)
_>И снова у тебя пробелы в знаниях. Даже если говорить о дефолте, то в соответствие со ссылкой выше это произошло в версии mysql 5.5 (которая вышла в 2010-м году).
Да, действительно, хотя дефолт был добавлен не в 5.5, а в 5.5.5, это произошло в середине 10-го года. Спасибо за устраненный пробел )))
Но сути дела это не меняет.
_>Несколько сообщений назад ты как раз писал о том, что эти направления не особо растут.
Совершенно верно, и это видно на вашем же графике.
_> Собственно для опровержения этого твоего утверждения и я приводил ссылку на попавшуюся под руку статью.
Д — логика. Тот факт, что в одном месте (или даже в нескольких), внедрили noSQL, совершенно не означает, что в целом он растет.
_>>>Однако ты тут утверждал, что подобных переходов никто не делает в принципе. IB>>Цитату можно? Где прям в принципе?
_>Да их много было. Например такая: _>
_>Иными словами, noSQL — это не замена SQL, а новый инструмент для нового сценария (Big Data).
_>или такая: _>
_>Попытались было впихнуть вместо SQL-я, но что-то пошло не так.
Прекрасно, а теперь поясните пожалуйста, по какой логике из этого следует, что в принципе никто не переходит?
В принципе, может кто-то и переходит, но общей картины это не меняет.
_>Как видишь, на практике вполне себе заменяют реляционные БД на различные nosql решения, в том числе и даже в таких консервативных местах, как банки.
Речь не о замене, а о том, в каких сценариях это происходит. Про OLAP и BigData я писал с самого начала, с чем спорим?
_>Естественно заменяют не все реляционные БД, а только подходящие для этого. Но сам факт замены это не отменяет...
Вот это новенькое, есть подходящие реляционные БД для замены, и есть не подходящие, оказывается? )))
Мы уже победили, просто это еще не так заметно...
Re[53]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Аааа, т.е. ты всё продолжаешь намекать на своё незнание русского языка (для тебя же "вдохновиться примером чего-то" и "заменить на это что-то" являются синонимами)...
Не, я намекаю на ваше неумение выражаться на нем так, чтобы все понимали ))
_>Это ты сейчас полную ерунду написал. В обоих случаях при изменение способа обхода коллекции в соответствие с новым типом коллекции (в данном случае обсуждалось добавление индекса по какому-то полю) будет исполняться новый код. Единственная разница заключается в том, что в случае linq этот код можно скачать готовым в виде некой библиотеки (правда скорее всего пожертвовав при этом производительностью), а в случае без Linq придётся написать самому (и то не факт — вполне возможно что есть готовые аналогичные библиотеки и без Linq).
Ну конечно же нет. Разница в том, что в одном случае придется править прикладной код, а в другом при замене коллекции, прикладной код не трогается, а в большинстве случаев, вообще никакой код не трогается, так как код работы с коллекцией уже в ней.
_>А что это ещё за эфемерная "эффективность" появилась у нас в обсуждение, если здесь мы говорили о вполне конкретной производительности?
Вот о ней и говорим.
_>Судя по ответам Sinclair'а соответствующей готовой библиотеки для linq не оказалось и "неожиданно" для написания linq варианта кода в этих условиях требуется намного больше усилий, чем при простом for'е. Как же так то, а? )))
Просто, наверное у вас опять не получилось прочитать ответ Антона правильно. Там довольно понятно написано, что усилий будет меньше ))
_>Ещё раз: у Linq нет никакой имплементации ни в какой СУБД, поэтому обсуждение его в том виде, в каком сего используют сейчас (в качестве надстройки над SQL), абсолютно не интересно в данной дискуссии.
Еще раз: совершенно без разницы, есть имплементация в какой-либо СУБД или нет. Коль скоро в данной дискуссии мы обсуждаем язык, который мог бы быть прототипом для работы с СУБД и этот язык таки работает с СУБД, то совершенно не важно через какой API он это делает, через SQL или через свой AST...
_>Так а почему до сих пор тут никто не выдвигал этого предложения (исполнения непосредственно Linq запросов на сервере) и не было его подробного обсуждения?
Ну вот, я выдвинул, как только речь до этого дошла. В других дискуссиях этот вопрос так же уже поднимался. В чем вопрос-то?
_>Ну так может тогда поделишься, какие на твой взгляд главные недостатки у SQL? )
В основном, мои претензии к SQL те же, что и у Антона — отсутствие средств декомпозиции, недостаточная выразительность и зоопарк реализаций.
Мы уже победили, просто это еще не так заметно...
Re[44]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Эм, ты серьёзно предлагаешь обсуждать код, нарушающий задокументированный инвариант? ) И вместо использования юнит-тестов, предлагаешь замедлить код рантаймовой проверкой? ))) S>Я, наверное, не вполне понимаю, о каких юнит тестах идёт речь.
Ну ты же писал про "Через два года кто-то третий в третьем месте вставил невинную штуку по добавлению элемента в начало списка.". Очевидно, что такой код не мог бы пройти через правильно написанные (проверяющие как минимум официальные инварианты) юнит-тесты.
S>Если юнит хочет возвращать отсортированный массив — пусть возвращает SortedList. Это позволит нам устранить лишние проверки, и заменить юнит-тестирование просто компиляцией.
Если этот SortedList будет формироваться просто через подстановку (т.е. аналог typdef), а не через сортировку, то почему бы и нет.
_>>Так при старте СУБД все файлы (пускай и записанные ею в предыдущей сессии) являются входными данными. Так что тогда полагается пересчитать все индексы при старте, а то мало ли кто их там правил, пока СУБД была отключена... S>Ну, вообще многие СУБД хранят и контрольные суммы — на случай, если кто-то вмешался в данные, "пока СУБД была отключена", и при расхождениях начинают восстанавливать данные. S>Но я бы провёл некоторую границу между случайным изменением вполне рабочего кода, и злонамеренным вмешательством в файл.
Ну т.е. теперь ты увидел, что вполне себе существуют ситуации, в которых ПО может нормально воспринимать предварительно отсортированные входные данные (например если это ПО само же и записывало их в предыдущей сессии).
_>>Ага, т.е. достаточно объявить функцию Where у класса и она будет всегда использоваться? Выглядит неплохо. Непонятно тогда почему на SO все писали, что мол двоичный поиск невозможно реализовать, т.к. IEnumerable не поддерживает произвольный доступ. Раз у нас есть доступ к "this" оригинального типа, то естественно никаких проблем не видно. S>Нельзя сделать двоичный поиск для IEnumerable. S>Можно — для своего SortedArray. Можно рискнуть и для банального T[], если сильно хочется приключений.
Это всё очевидно. Я как раз и спрашивал, если способ чтобы вызывался наш код для SortedArray. Раз он есть, то не вижу особых проблем с написанием двоичного поиска. Кстати, странно что таких готовых библиотечных функций не видно и что народ на SO говорит о невозможности такого.
_>>А как предполагается делать анализ нашего предиката? Нам же при двоичном поиске не подходит просто запуск Func для каждого элемента... S>Вкратце — сигнатура метода будет немножко другой: S>
S>Нам передаётся вместо делегата его AST-представление, которое мы анализируем. Точно так же, как это делает linq2sql или linq2db. S>Подробности можно просто посмотреть в исходниках i4o.
Гммм, для работы с коллекциями это по идее уж слишком много оверхеда. Такое по идее можно рассматривать только при многомиллионных коллекциях.
_>>Способ обхода зависит (естественно это всё определяется на этапе компиляции) от типа входного итератора. Если тот относится к концепту RandomAccessIterator, то будет O(logN), а иначе O(N). S>RandomAccessIterator не имеет никакого отношения к отсортированности списка.
Конечно. Я просто пояснил, что там два метода обхода есть. А так конечно же все функции из блока двоичного поиска требуют чтобы входные данные были отсортированными. Собственно так давным давно было, ещё в древней STL http://en.cppreference.com/w/cpp/algorithm/lower_bound.
S>>>То, что написано в псевдокоде, это и есть linq за вычетом query comprehensions. _>>Нет, на псевдокоде задана как раз эмуляция диапазонов для случая простейшего массива (задание двух индексов + самого массива равносильны заданию двух итераторов в диапазоне). И это намного удобнее и эффективнее IEnumerable . S>Linq не имеет к IEnumerable почти никакого отношения. Кроме того, что есть специальный класс Enumerable, в котором определены методы-расширения, позволяющие использовать IEnumerable в query comprehensions.
Ну в данном ответвление беседы мы же обсуждали применение Linq к разботе с коллекциями. И я что-то не видел тут других походов, кроме IEnumerable.
S>Мы можем завести свой тип Range, определив его подходящим для нас образом, и полностью заменить всю математику linq.
Range — это абстракция над итераторами. В начале надо обдумать как можно ввести итераторы без оверхеда в язык типа C#.
S>В том числе мы можем сделать отложенное вычисление, построив полное-полное дерево выражений на весь конвеер, сгенерировать для него dynamicMethod и вручную выполнить инлайнинг произвольной агрессивности. S>Основная беда — в том, что сейчас компилятор с какого-то бодуна строит Expression<> динамически на каждом вызове, вместо однократной инициализации. Из-за этого невозможно прозрачно для пользователя кэшировать результат анализа Expression Tree — его надо прикапывать вручную.
Согласен. Более того, у меня даже более жёсткая позиция по данному вопросу: я считаю что подобно надо просчитывать не при инициализации приложения, а при его компиляции.
Re[44]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>>Смотрим сюда: https://ru.wikipedia.org/wiki/InnoDB и видим что поддержка появилась в версии 3.23. А с учётом того, что первая публичная версия имела номер 3.21, то мне не кажется, что они реально сосредотачивались на поддержке только одного движка (ISAM)... ))) IB>А если смотреть не на номера версий, а на года (начало 90-х ISAM и начало двухтысячных InnoDB), то становится очевидно, что ничего кроме ISAM у них и в мыслях не было. IB>У ребят была конкретная цель, о которой они не стесняясь написали в той же вики — более производительный и удобный API к ISAM. Так что не надо презерватив на глобус натягивать и манипулировать номерами версий. =)
Нет, смотреть номера версий как раз очень полезно, т.к. это проверяемые факты, а не какие-то слухи... Например смотрим сюда https://en.wikipedia.org/wiki/MySQL и видим, что первый официальный релиз mysql был в 1998-м году (сразу версия 3.21), а уже через 2 года (в 3.23) появилась поддержка InnoDB. И тут же делаем выводы, что твои рассуждения о начале 90-ых и ISAM не имеют к mysql никакого отношения.
_>>Как видишь, на практике вполне себе заменяют реляционные БД на различные nosql решения, в том числе и даже в таких консервативных местах, как банки. IB>Речь не о замене, а о том, в каких сценариях это происходит. Про OLAP и BigData я писал с самого начала, с чем спорим?
Ну так многие OLAP системы до сих пор крутятся на РСУБД и соответственно ожидают замены. Т.е. сам процесс замены РСУБД на nosql решения же идёт не так ли? Пускай и не во всех возможных областях...
_>>Естественно заменяют не все реляционные БД, а только подходящие для этого. Но сам факт замены это не отменяет... IB>Вот это новенькое, есть подходящие реляционные БД для замены, и есть не подходящие, оказывается? )))
Я надеюсь ты тут не перепутал БД и СУБД, как некий изредка встревающий (и почти всегда не по делу) в беседу коллега рядом? )))
Re[10]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Ну ты же писал про "Через два года кто-то третий в третьем месте вставил невинную штуку по добавлению элемента в начало списка.". Очевидно, что такой код не мог бы пройти через правильно написанные (проверяющие как минимум официальные инварианты) юнит-тесты.
Предположим, что такие юнит тесты всё же есть. Что, конечно же, далеко не факт — потому как потенциальных инвариантов дохрена, и на все юнит-тестов не напишешься.
Но у нас запросто окажется, что обычно добавляемый элемент равен нулю, и потому инвариант не нарушает. Но иногда он нулю не равен, и с некоторой вероятностью портит данные.
Такое нарушение вы ни юнит-тестом, ни даже при помощи измерения code coverage не поймаете.
S>>Если юнит хочет возвращать отсортированный массив — пусть возвращает SortedList. Это позволит нам устранить лишние проверки, и заменить юнит-тестирование просто компиляцией. _>Если этот SortedList будет формироваться просто через подстановку (т.е. аналог typdef), а не через сортировку, то почему бы и нет.
_>Ну т.е. теперь ты увидел, что вполне себе существуют ситуации, в которых ПО может нормально воспринимать предварительно отсортированные входные данные (например если это ПО само же и записывало их в предыдущей сессии).
Такие ситуации — очень редкие, и потенциально взрывоопасные. Их имеет смысл рассматривать отдельно, и подробно оговаривать в документации / комментариях к коду.
А то, что вы предполагаете везде оперировать голыми массивами, просто надеясь на то, что у вас хватит юнит-тестов для покрытия всех code paths — против моих убеждений.
_>Это всё очевидно. Я как раз и спрашивал, если способ чтобы вызывался наш код для SortedArray. Раз он есть, то не вижу особых проблем с написанием двоичного поиска. Кстати, странно что таких готовых библиотечных функций не видно и что народ на SO говорит о невозможности такого.
Я полагаю, что вы неверно проинтерпретировали либо вопрос, либо ответ.
_>Гммм, для работы с коллекциями это по идее уж слишком много оверхеда. Такое по идее можно рассматривать только при многомиллионных коллекциях.
Ну, i4o обгоняет линейный поиск уже на вполне гражданских объёмах. Тут подкупает невыносимая лёгкость замены реализации, когда размеры наших коллекций от дюжин переходят к миллионам.
_>Конечно. Я просто пояснил, что там два метода обхода есть. А так конечно же все функции из блока двоичного поиска требуют чтобы входные данные были отсортированными. Собственно так давным давно было, ещё в древней STL http://en.cppreference.com/w/cpp/algorithm/lower_bound.
Вот это меня и беспокоит.
_>Range — это абстракция над итераторами. В начале надо обдумать как можно ввести итераторы без оверхеда в язык типа C#.
Как раз это — значительно проще, чем linq. Enumerator паттерн не основан ни на каких интерфейсах, поэтому можно а) объявить свой тип struct Iterator<T>: IEnumerator<T>, б) тип Range тоже можно сделать структурой, и возвращать из метода GetEnumerator() прямо соответствующий struct.
Тогда код типа foreach(var i in range) будет вполне себе инлайниться и получать эффективность, близкую к С++.
_>Согласен. Более того, у меня даже более жёсткая позиция по данному вопросу: я считаю что подобно надо просчитывать не при инициализации приложения, а при его компиляции.
Тут опять упираемся в вопросы того, что и где можно инлайнить.
Потому что вот, допустим, наблюдаем мы вызов типа
z.Where(x=>x.Age>minAge);
Ок, мы это разворачиваем нужным образом. То есть там прямо статически генерируется интересное нам AST. Тут как бы есть проблемы, связанные с тем, что AST — это дерево объектов, а константы объектов хранить в сборках нельзя, поэтому все объекты (например, атрибуты метаданных) хранятся в виде набора параметров для вызова конструкторов, и вычисляются при загрузке сборки (то есть при инициализации приложения). Но даже если мы этими проблемами пренебрежём, то мы всё ещё не можем выполнить, к примеру, генерацию SQL (или того же MSIL) на этапе компиляции: просто потому, что эта генерация — и есть выполнение where.
То есть нам потребуется наличие кода этого where на момент компиляции — а он у нас берётся из библиотеки, которая собирается отдельно, и вообще, возможно, позже, чем наше приложение. Если у нас есть прямо исходный код этого where, то мы можем проинлайнить туда вызовы конструкторов Expression Tree, и попытаться выполнить этот where во время компиляции — ну, чтобы посмотреть, нельзя ли что-то там улучшить. Но там опять косвенные вызовы — то есть мы не просто пишем код в стиле
if(expr is ComparisonExpression)
if((expr as ComparisonExpression).FirstArgument is MemberAccessExpression))
if(((expr as ComparisonExpression).FirstArgument as MemberAccessExpression).MemberInfo == this.SortPropertyInfo)...
Тут можно было бы, конечно же, сразу же вычислить все эти is и выкинуть ненужные ветки кода, оставив только чистый и незамутнённый код бинарного поиска.
Нет — там же визиторы, которые вызывают визиторы
То есть надо инлайнить нахрен всё на десять уровней вглубь, не обращая внимания на code size, в надежде на constant propagation и dead code elimination.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[54]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>>Это ты сейчас полную ерунду написал. В обоих случаях при изменение способа обхода коллекции в соответствие с новым типом коллекции (в данном случае обсуждалось добавление индекса по какому-то полю) будет исполняться новый код. Единственная разница заключается в том, что в случае linq этот код можно скачать готовым в виде некой библиотеки (правда скорее всего пожертвовав при этом производительностью), а в случае без Linq придётся написать самому (и то не факт — вполне возможно что есть готовые аналогичные библиотеки и без Linq). IB>Ну конечно же нет. Разница в том, что в одном случае придется править прикладной код, а в другом при замене коллекции, прикладной код не трогается, а в большинстве случаев, вообще никакой код не трогается, так как код работы с коллекцией уже в ней.
Ну так в таком случае вызвать его в императивном коде без Linq будет одно удовольствие. )))
_>>Судя по ответам Sinclair'а соответствующей готовой библиотеки для linq не оказалось и "неожиданно" для написания linq варианта кода в этих условиях требуется намного больше усилий, чем при простом for'е. Как же так то, а? ))) IB>Просто, наверное у вас опять не получилось прочитать ответ Антона правильно. Там довольно понятно написано, что усилий будет меньше ))
Вообще то он как раз сказал обратное. Но давай послушаем не его, а твоё мнение и аргументацию. И так у нас есть банальный массив int[], из которого мы с помощью linq берём подмножество по условию значений допустим от 0 до 1000. Это очевидный код и на linq и при императивном коде. Теперь меняем начальные условия задачи: известно, что наш начальный массив int[] отсортирован и нам соответственно для максимальной эффективности надо применить двоичный поиск. Как будет выглядеть твоё решение на linq этой простейшей задачки? Императивно она естественно решается элементарно.
_>>Так а почему до сих пор тут никто не выдвигал этого предложения (исполнения непосредственно Linq запросов на сервере) и не было его подробного обсуждения? IB>Ну вот, я выдвинул, как только речь до этого дошла. В других дискуссиях этот вопрос так же уже поднимался. В чем вопрос-то?
Да ничего такого, не считая того, что уже 48 страниц в этой темке и только сейчас от тебя появились какие-то попытки конструктива. ))) И то, "выжатые" мною и пока что без всякой аргументации.
_>>Ну так может тогда поделишься, какие на твой взгляд главные недостатки у SQL? ) IB>В основном, мои претензии к SQL те же, что и у Антона — отсутствие средств декомпозиции, недостаточная выразительность и зоопарк реализаций.
(см. предпоследний абзац) моего сообщения в самом самом начале темы. Забавно в том смысле, что при таких взглядах вроде бы непонятно о чём нам спорить... )))
Хотя на самом деле я заметил, что тут просто есть несколько специфических маркеров, при упоминание которых даже у обычно адекватных собеседников начинается неконтролируемый приступ противоречия из принципа, вне зависимости от темы изначальной дискуссии. В данной теме из таких маркеров всплыли:
— упоминание nosql СУБД. Видимо это у многих больная мозоль из-за необходимости переобучения, чтобы не отстать от индустрии.
— критика Linq. Видимо у многих это вроде священной коровы, подмечать очевидные недостатки которой, просто ужасно.
Re[55]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>>>Судя по ответам Sinclair'а соответствующей готовой библиотеки для linq не оказалось и "неожиданно" для написания linq варианта кода в этих условиях требуется намного больше усилий, чем при простом for'е. Как же так то, а? ))) IB>>Просто, наверное у вас опять не получилось прочитать ответ Антона правильно. Там довольно понятно написано, что усилий будет меньше ))
_>Вообще то он как раз сказал обратное.
Синклер сказал, что усилий будут меньше. На linq. В императивном коде — больше. Потому как в императивном коде тебе придется все циклы переписать, прежде чем ты получишь внятное решение.
_>Хотя на самом деле я заметил, что тут просто есть несколько специфических маркеров, при упоминание которых даже у обычно адекватных собеседников начинается неконтролируемый приступ противоречия из принципа, вне зависимости от темы изначальной дискуссии. В данной теме из таких маркеров всплыли:
Приступ противоречия это у тебя что ли ? Остальные вроде как и два года назад, и пять лет назад тоже самое говорили.
Re[45]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Нет, смотреть номера версий как раз очень полезно, т.к. это проверяемые факты, а не какие-то слухи... Например смотрим сюда https://en.wikipedia.org/wiki/MySQL и видим, что первый официальный релиз mysql был в 1998-м году (сразу версия 3.21),
Очень удобно, конечно, читать только то что выгодно, но нет. ))
Original development of MySQL by Widenius and Axmark began in 1994. The first version of MySQL appeared on 23 May 1995. It was initially created for personal usage from mSQL based on the low-level language ISAM, which the creators considered too slow and inflexible. They created a new SQL interface, while keeping the same API as mSQL.
То есть, как я и писал, задача была не поддерживать несколько движков, а сделать более удобный API к SAM, коим и явился SQL. И начата работа была в 94-м, минимум за 5 лет до того, как InnoDB появился на горизонте. (Очевидно, что в этом вопросе, совершенно не важно когда был первый официальный релиз)
_> а уже через 2 года (в 3.23) появилась поддержка InnoDB. И тут же делаем выводы, что твои рассуждения о начале 90-ых и ISAM не имеют к mysql никакого отношения.
Как обычно, неверные выводы вы делаете, из ложных предпосылок )
Мы уже победили, просто это еще не так заметно...
Re[55]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Ну так в таком случае вызвать его в императивном коде без Linq будет одно удовольствие. )))
Можем перевести дискуссию в плоскость удовольствия, советую попробовать как это будет на Linq, первая доза бесплатно )))
_>Вообще то он как раз сказал обратное.
Вообще-то как раз нет.
_> Но давай послушаем не его, а твоё мнение и аргументацию.
Вы с начала с ним закончите, а я послушаю, чтобы не повторяться )
_>Да ничего такого, не считая того, что уже 48 страниц в этой темке и только сейчас от тебя появились какие-то попытки конструктива.
От конструктива я никогда не уклоняюсь, но пока от оппонентов его не было вообще...
_> Забавно в том смысле, что при таких взглядах вроде бы непонятно о чём нам спорить... )))
Ну, например, об идее добавить больше императивности в SQL. Или об идее посмотреть на NoSQL языки запросов в качестве образца.
_>Хотя на самом деле я заметил, что тут просто есть несколько специфических маркеров, при упоминание которых даже у обычно адекватных собеседников начинается неконтролируемый приступ противоречия из принципа, вне зависимости от темы изначальной дискуссии.
Пока противоречия из принципа видно только у вас ))
_>- упоминание nosql СУБД. Видимо это у многих больная мозоль из-за необходимости переобучения, чтобы не отстать от индустрии.
Вот это выглядит особенно смешно. )) Скорее это адепты noSQL не в состоянии осилить РСУБД и поэтому запихивают эти изделия где можно и где нельзя. Совсем недавно пришлось реанимировать одно такое изделие, от создателей хита "noSQL быстрее" и хипста-оперы "SQL устарел". После такого, у кого хочешь глаз дергаться будет.
Но дело даже не в этом. Тут в одной дискуссии прозвучала довольно здравая мысль — с тех пор, как NoSQL базы поддержали SQL запросы, а РСУБД поддержали XML и JSON, то разница между ними только в том, что у первых подсистема хранения данных написана через жопу. И мысль эта мне кажется довольно верной.
_>- критика Linq. Видимо у многих это вроде священной коровы, подмечать очевидные недостатки которой, просто ужасно.
Просто вы опять нашли недостатки где-то не там )))
Мы уже победили, просто это еще не так заметно...
Re[11]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Ну т.е. теперь ты увидел, что вполне себе существуют ситуации, в которых ПО может нормально воспринимать предварительно отсортированные входные данные (например если это ПО само же и записывало их в предыдущей сессии). S>Такие ситуации — очень редкие, и потенциально взрывоопасные. Их имеет смысл рассматривать отдельно, и подробно оговаривать в документации / комментариях к коду.
Однако эту ситуацию можно найти практически в любой СУБД (где есть записываемые на диск индексы) и это всего лишь один из примеров (просто очень близкий к обсуждаемой теме).
S>А то, что вы предполагаете везде оперировать голыми массивами, просто надеясь на то, что у вас хватит юнит-тестов для покрытия всех code paths — против моих убеждений.
Да можно даже и без юнит-тестов. На мой взгляд вполне достаточно использование соответствующего говорящего типа, пускай он и всего лишь синоним обычного массива (это я про typedef vector my_sorted_vector). Так то у программиста всегда есть способы сломать код, сделав что-то запрещённое правилами, но мы же не рассматриваем все подобные сценарии как реальные...
_>>Гммм, для работы с коллекциями это по идее уж слишком много оверхеда. Такое по идее можно рассматривать только при многомиллионных коллекциях. S>Ну, i4o обгоняет линейный поиск уже на вполне гражданских объёмах. Тут подкупает невыносимая лёгкость замены реализации, когда размеры наших коллекций от дюжин переходят к миллионам.
С линейный поиском то понятно. Я говорю про оверхед относительно двоичного поиска, но без linq. )
_>>Range — это абстракция над итераторами. В начале надо обдумать как можно ввести итераторы без оверхеда в язык типа C#. S>Как раз это — значительно проще, чем linq. Enumerator паттерн не основан ни на каких интерфейсах, поэтому можно а) объявить свой тип struct Iterator<T>: IEnumerator<T>, б) тип Range тоже можно сделать структурой, и возвращать из метода GetEnumerator() прямо соответствующий struct. S>Тогда код типа foreach(var i in range) будет вполне себе инлайниться и получать эффективность, близкую к С++.
Чтобы была эффективность уровня 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>Тут опять упираемся в вопросы того, что и где можно инлайнить. S>Потому что вот, допустим, наблюдаем мы вызов типа S>
z.Where(x=>x.Age>minAge);
S>Ок, мы это разворачиваем нужным образом. То есть там прямо статически генерируется интересное нам AST. Тут как бы есть проблемы, связанные с тем, что AST — это дерево объектов, а константы объектов хранить в сборках нельзя, поэтому все объекты (например, атрибуты метаданных) хранятся в виде набора параметров для вызова конструкторов, и вычисляются при загрузке сборки (то есть при инициализации приложения). Но даже если мы этими проблемами пренебрежём, то мы всё ещё не можем выполнить, к примеру, генерацию SQL (или того же MSIL) на этапе компиляции: просто потому, что эта генерация — и есть выполнение where. S>То есть нам потребуется наличие кода этого where на момент компиляции — а он у нас берётся из библиотеки, которая собирается отдельно, и вообще, возможно, позже, чем наше приложение. Если у нас есть прямо исходный код этого where, то мы можем проинлайнить туда вызовы конструкторов Expression Tree, и попытаться выполнить этот where во время компиляции — ну, чтобы посмотреть, нельзя ли что-то там улучшить. Но там опять косвенные вызовы — то есть мы не просто пишем код в стиле S>
S> if(expr is ComparisonExpression)
S> if((expr as ComparisonExpression).FirstArgument is MemberAccessExpression))
S> if(((expr as ComparisonExpression).FirstArgument as MemberAccessExpression).MemberInfo == this.SortPropertyInfo)...
S>
S>Тут можно было бы, конечно же, сразу же вычислить все эти is и выкинуть ненужные ветки кода, оставив только чистый и незамутнённый код бинарного поиска. S>Нет — там же визиторы, которые вызывают визиторы S>То есть надо инлайнить нахрен всё на десять уровней вглубь, не обращая внимания на code size, в надежде на constant propagation и dead code elimination.
Я не изучал насколько реально реализовать подобное на языках типа C#. Однако в C++ это не просто реализуемо в теории, но и вполне себе существует на практике и не первый год. Единственные нюанс, который можно отметить в этих реализациях: код этой самой сторонней библиотеки с where на C++ реализуется через шаблоны.
Re[46]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>> а уже через 2 года (в 3.23) появилась поддержка InnoDB. И тут же делаем выводы, что твои рассуждения о начале 90-ых и ISAM не имеют к mysql никакого отношения. IB>Как обычно, неверные выводы вы делаете, из ложных предпосылок )
Ух как утомили эти глупости на пустом месте. Простой вопрос: продукт под названием mysql появился в начале 90-ых или в конце?
Re[56]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>>Вообще то он как раз сказал обратное. IB>Вообще-то как раз нет.
Он сказал дословно:
Да, для работы с массивами интов линк малополезен.
и предложил рассмотреть другие задачи. С которыми тоже в итоге оказалось всё гораздо сложнее, но там хотя бы было поле для дискуссии... )))
_>> Но давай послушаем не его, а твоё мнение и аргументацию. IB>Вы с начала с ним закончите, а я послушаю, чтобы не повторяться )
Потому как сказать нечего, так же как и в случае с более быстрым чем for linq? )))
_>>Да ничего такого, не считая того, что уже 48 страниц в этой темке и только сейчас от тебя появились какие-то попытки конструктива. IB>От конструктива я никогда не уклоняюсь, но пока от оппонентов его не было вообще...
Конструктив — это не означает только то, с чем ты согласен. Это означает предложение хоть чего-то нового, а не только критику.
_>> Забавно в том смысле, что при таких взглядах вроде бы непонятно о чём нам спорить... ))) IB>Ну, например, об идее добавить больше императивности в SQL. Или об идее посмотреть на NoSQL языки запросов в качестве образца.
Не в качестве образца, а в качестве источника идей. Т.е. на мой взгляд при разработке новой технологии/языка надо брать всё лучшее из уже существующих. И идея о передаче произвольного императивного кода в запросе — одна из таких идей. Которую кстати можно увидеть во многих nosql решениях.
_>>- упоминание nosql СУБД. Видимо это у многих больная мозоль из-за необходимости переобучения, чтобы не отстать от индустрии. IB>Вот это выглядит особенно смешно. )) Скорее это адепты noSQL не в состоянии осилить РСУБД и поэтому запихивают эти изделия где можно и где нельзя. Совсем недавно пришлось реанимировать одно такое изделие, от создателей хита "noSQL быстрее" и хипста-оперы "SQL устарел". После такого, у кого хочешь глаз дергаться будет.
Действительно больная мозоль. )
IB>Но дело даже не в этом. Тут в одной дискуссии прозвучала довольно здравая мысль — с тех пор, как NoSQL базы поддержали SQL запросы, а РСУБД поддержали XML и JSON, то разница между ними только в том, что у первых подсистема хранения данных написана через жопу. И мысль эта мне кажется довольно верной.
Это неверная мысль, т.к. она следует из непонимания причин появления (точнее реинкарнации) nosql решений. Использование json/xml — это особенность документо-ориентированных СУБД, которые являются всего лишь маленьким подмножеством noslq решений. Где там json/xml у какого-нибудь HBase или Redis'a? )))
_>>- критика Linq. Видимо у многих это вроде священной коровы, подмечать очевидные недостатки которой, просто ужасно. IB>Просто вы опять нашли недостатки где-то не там )))
У linq есть множество очевидных недостатков. Причём как концептуальных (как раз связанных с моделью SQL), так и в реализации (динамическое построение выражений в рантайме, использование рефлексии и т.п.). Однако при их упоминание у некоторых коллег по данному форуму почему-то всегда начинаются неконтролируемые возражения, причём всегда без всякой технической (чтобы с цифрами замеров и т.п.) аргументации, а просто из принципа. Вот реально священная корова для некоторых. Причём это только на этом форуме и уже давно — я уже даже привык и не обращаю особого внимания на данную особенность. )))