Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
S>>Тоесть итог всей этой болтовни таков. Ты против yield потому, что он с ленивость привносит накладные расходы.
I>Очевидно, это не так. Я спокойно использую yield там, где это не является узким место. И я точно знаю, где начинается это узкое место.
S>>Какие именно? MoveNext и Current я так понимаю. Но на этом Linq то и основан.
I>Linq основан на IQueryable, а IEnumerable нужн рассматривать как оптимизацию частного случая.
И откуда ты ото взял. При этом бОльшая часть линка используется именно для IEnumerable.
Деревья выражений не используются в IEnumerable, но ты не против них!
S>>А List этих расходов не привносит, хотя нужна лишняя память для заполнение Lista даже если эти данные не понадобятся и лишние вызовы лямд если эти данные уже и не нужны
I>В большинстве случаев дополнительная память не нужна. В остальных случаях тоже не все однозначно. Ленивый процессинг можно сорганизовать самыми разными способами с производительностью не хуже IEnumerable.
Еще раз List реализует IEnumerable, но заполнение List ну ни хрена не ленива!! I>Естественно, я не предлагаю везде заменить IEnumerable массивом. Это стоит делать в числодробилках, когда устраняем узкое место. I>Чтото мне подсказывает,через три сообщение напишешь "а ты предлагаешь везде отказаться от IEnumerable и перевести всё на массивы"
Так массив и реализует IEnumerable.
В числодробилках можно применять Linq и https://github.com/antiufo/roslyn-linq-rewrite
Или другие способы генерации кода например Source Generator https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/
и солнце б утром не вставало, когда бы не было меня
Re[36]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
I>>Ты пока не показал, как xml, db и подобные вещи читать твоим IEnumerable, что бы это было максимально эффективно. S> Ты чего издеваешься!!! Я тебе ссылку на Linq to XML давал!!!!!
Я не ходил по ссылке, поверил тебе на слово.
Похоже, судя по твоим воплям, ты снова написал не то, что думал?
I>>В JS, раз уж ты вспомнил, есть yield. Однако же, в RX процессинг ленивый, а обходятся без yield I>>https://github.com/ReactiveX/rxjs/search?q=yield I>>Ажно 11 раз, и те в документации и тестах I>>Теперь тебе понятно, что yield для RX это вещь сильно опциональная?
S> Еще раз писать ленивые итераторы это ручная работа того, что делает yield.
Очевидно — нет. Ты просто не в курсе, как это делается в RX.
Еще раз:
Вместо yield a пишем observer.next(a)
Возьми паузу и подумай.
S>Что и как генерит yield копируй и вставляй в код. В свое врямя то же самое развертывался async await в JS
Как видишь — сравнимое количество кода и никакие это не 2 строчки.
I>>Дорого, я в курсе. Иногда это обосновано, если перформанс не актуален, а нужно иметь один и тот же код против разных источников данных. S>
Что конкретно тебя смущает?
I>>То есть, слив Или ты считаешь свой код примерами работы с mssql ? S>
Итого — таки слив.
I>> Каким образом по IEnumerable построить SQL ?
Итак — ответа нет.
I>>Используются, просто ты про это ничего не знаешь. Если код написан для BD, нет никакого смысла городить огород, если в некоторых случая нужно таскать данные из коллекций. I>>Используем один и тот же код против BD и коллекций, всех делов.
S> Я с тебя хренею. Почитай себя. Все твои доводы против yield.
Это не мои доводы, а твоя интерпретация
S>yield это херня так как не используется в IQueryable.
Очевидно, я такого не говорил. Более того — я нигде не называю yield херней. Ты бы прекратил додумывать?
>Но IQueryable хотя и не используется в IEnumerable хотя IQueryable наследуется от IEnumerable
Это не важно, что от чего наследуется. При помощи IQueryable можно сделать всё, добавляя провайдер.
С IEnumerable так не получится.
Re[36]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
S>И. Еще раз там используются ленивые иераторы?
Итератор всегда ленивый. Никто тебя не заставляет вызывает MoveNext больше, чем тебе надо. И создавать итератор, раньше чем тебе надо, не нужно.
И копировать данные для итератора при создании тоже не нужно.
то есть, всё и так ленивое, без твоих yield.
S>Сколько в итоге будет итераций? S>https://stackoverflow.com/questions/21782380/are-java-8-streams-the-same-as-net-ienumerable
Столько же. Посмотри интерфейс этого стрима и прекрати пороть чушь.
I>>Четвертый раз — вместо x[i] у тебя MoveNext, проход через switch, присваивание Current и чтение Current I>>И вот эта каша крайне плохо инлайнится, а следовательно ест больше чем весит. I>>Заметь — это уже в четвертый раз я пишу, а до тебя не доходит.
S> Ну в итоге вывод один. Ты против yield,
А ты, упорный. Раз я с тобой не согласен, значит — против yield
> но сам то Linq построен на ленивом создании итераторов.
Что значит "ленивое создание итераторов" ? Он и до введения yield создавался только по требованию, т.е. ленивым образом. А сам итератор и без тебя ленивый.
S>А yield как раз этим и занимается. Так понятнее.
Нет, не понятно. Итератор сам по себе ленивый, и так было до yield. И создавался ленивым образом, тоже до yield.
S> Для тебя лишние итерации, вызов лямбда выражений, селекты ничего не стоят!!!
Так было и до введения yield. Это бенефиты IEnumerable, они работают и без yield.
I>>>>Именно. Профайлер утверждает, что экономия может быть и полтора, и два, и даже десять раз. S>>>Ну то есть ты за выполнение слева направо. S> Где и какой профайлер?? Покажи данные!
Может тебе и код дать и пароли?
I>>Откуда такой вывод? Я и слева направо обгоню это IEnumerable с не меньшим бенефитом. S> Даааа!! вот твой же пример с миллионами строк пр этом первая же строка удовлетворяе условию. S>Вот такие у тебя профайлеры. Но минус то ты мне ставишь!!
Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог.
Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание.
I>>Если собираешся итерировать по индексу, лучше запрашивать массив явно — исключается целый класс ошибок. S> Даа. А если нужно передать из метода и вернуть из вызываемого метода. S>Ты никогда с не работал с пользовательским выбором условий и выводом, когда вариаций куча, а пользователь интерактивно, динамически сам выбирает конструкцию запроса.
Не смеши людей. Я портировал часть Linq и ODATA на JavaScript, а что сделал ты ?
I>>Вот снова ересь — ленивость создаёт сам IEnumerable и никак иначе. Вобщем, каша. То одно пишешь, то другое, прямо противоположное S>Нет. Заполнение List не лениво!!!!!
А зачем мне list если мне нужна только итерация? Создаем итератор, итерируемся, пока это нужно, профит. Все что надо — один класс создаём явно. yield — делает ровно то же, но не явно. Вся разница. И ленивости в каждом случае ровно одинаково.
S>Вот именно, сам разберись. Пока все не в тему. И ну и явно ты не разобрался с темой. S>Почитай https://pvs-studio.com/ru/b/0808/#ID4EFF844D56
Разобрался примерно в 2003м году на корутинах Питона, а в 2008 нашел в С# yield
Re[36]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
I>>Linq основан на IQueryable, а IEnumerable нужн рассматривать как оптимизацию частного случая. S>И откуда ты ото взял. При этом бОльшая часть линка используется именно для IEnumerable. S>Деревья выражений не используются в IEnumerable, но ты не против них!
Деревья нужны что бы строить скажем SQL. Добавил пров — получил итерацию.
С IEnumerable так невозможно.
S> Еще раз List реализует IEnumerable, но заполнение List ну ни хрена не ленива!!
Когда тебе надо по одному источнику проходить несколько раз, что вобщем частый случай, издержки от yield и тотальной ленивости возрастают до небес.
S>Или другие способы генерации кода например Source Generator S>https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/
На всякий — я портировал часть Linq и ODATA на JavaScript. Просто что бы ты представлял, откуда у меня познания в Linq и его применениях.
Re[37]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
I>>>Ты пока не показал, как xml, db и подобные вещи читать твоим IEnumerable, что бы это было максимально эффективно. S>> Ты чего издеваешься!!! Я тебе ссылку на Linq to XML давал!!!!!
I>Ты пишешь "Xml там IQueryable на самом то деле. ". Смотри сам http://rsdn.org/forum/flame.comp/7994997.1
public class Pair<T> : IPair<T>, IEnumerable<T>
{
// ...
// The iterator is expanded into the following
// code by the compiler.public virtual IEnumerator<T> GetEnumerator()
{
__ListEnumerator result = new __ListEnumerator(0);
result._Pair = this;
return result;
}
public virtual System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
return new GetEnumerator();
}
private sealed class __ListEnumerator<T> : IEnumerator<T>
{
public __ListEnumerator(int itemCount)
{
_ItemCount = itemCount;
}
Pair<T> _Pair;
T _Current;
int _ItemCount;
public object Current
{
get
{
return _Current;
}
}
public bool MoveNext()
{
switch (_ItemCount)
{
case 0:
_Current = _Pair.First;
_ItemCount++;
return true;
case 1:
_Current = _Pair.Second;
_ItemCount++;
return true;
default:
return false;
}
}
}
}
Покажи во что это преобразуется в observer.next(a)
I>Это не важно, что от чего наследуется. При помощи IQueryable можно сделать всё, добавляя провайдер. I>С IEnumerable так не получится.
То есть минус ты мне поставил за то, что IEnumerable так не может при работе с БД, поэтому yield отстой и он не нужен и без него Linq и без него линк прекрасно обходится!
За что минус!!!!
и солнце б утром не вставало, когда бы не было меня
Re[37]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
S>>И. Еще раз там используются ленивые иераторы?
I>Итератор всегда ленивый. Никто тебя не заставляет вызывает MoveNext больше, чем тебе надо. И создавать итератор, раньше чем тебе надо, не нужно. I>И копировать данные для итератора при создании тоже не нужно. I>то есть, всё и так ленивое, без твоих yield.
Можно сказать, что каждый блок кода, между операторами yield return выполняется отложенно (lazily) только после очередного вызова метода MoveNext. Именно на этом основана ленивость библиотеки LINQ, которая построена в виде методов расширения интерфейсов IEnumerable и IEnumerable<T>.
Тебе обязательно нужно поставить минус!!!! S>>Сколько в итоге будет итераций? S>>https://stackoverflow.com/questions/21782380/are-java-8-streams-the-same-as-net-ienumerable
I>Столько же. Посмотри интерфейс этого стрима и прекрати пороть чушь.
I>>>Четвертый раз — вместо x[i] у тебя MoveNext, проход через switch, присваивание Current и чтение Current I>>>И вот эта каша крайне плохо инлайнится, а следовательно ест больше чем весит. I>>>Заметь — это уже в четвертый раз я пишу, а до тебя не доходит.
Ты издеваешься? Я тебе привожу ссылки где написано, что ленивости там никакой нет.
Ты должен доказать, что товарищ не прав! S>> Ну в итоге вывод один. Ты против yield,
I>А ты, упорный. Раз я с тобой не согласен, значит — против yield
Минус за что! >> но сам то Linq построен на ленивом создании итераторов.
I> Что значит "ленивое создание итераторов" ? Он и до введения yield создавался только по требованию, т.е. ленивым образом. А сам итератор и без тебя ленивый.
List создается то того как дергается его MoveNext, и дергает родительский MoveNext!!! S>>А yield как раз этим и занимается. Так понятнее.
I>Нет, не понятно. Итератор сам по себе ленивый, и так было до yield. И создавался ленивым образом, тоже до yield.
Дааааа. То есть ты про List так и не ответил. S>> Для тебя лишние итерации, вызов лямбда выражений, селекты ничего не стоят!!!
I>Так было и до введения yield. Это бенефиты IEnumerable, они работают и без yield.
Еще раз List это IEnumerable но он нихрена не ленив.
I>>>Откуда такой вывод? Я и слева направо обгоню это IEnumerable с не меньшим бенефитом. S>> Даааа!! вот твой же пример с миллионами строк пр этом первая же строка удовлетворяе условию. S>>Вот такие у тебя профайлеры. Но минус то ты мне ставишь!!
I>Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог. I>Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание.
То есть выполнить 5 создания классов, вызов лямбд будет больше чем миллионы вызовов [x] лямбд и селектов.
Я хренею!!!
I>Не смеши людей. Я портировал часть Linq и ODATA на JavaScript, а что сделал ты ?
Ну ты молодец!! Я так херню всякую пишу и тебе в подметки не гожусь. I>>>Вот снова ересь — ленивость создаёт сам IEnumerable и никак иначе. Вобщем, каша. То одно пишешь, то другое, прямо противоположное S>>Нет. Заполнение List не лениво!!!!!
I>А зачем мне list если мне нужна только итерация? Создаем итератор, итерируемся, пока это нужно, профит. Все что надо — один класс создаём явно. yield — делает ровно то же, но не явно. Вся разница. И ленивости в каждом случае ровно одинаково.
Какой итератор ты создаешь? List тоже итератор
S>>Вот именно, сам разберись. Пока все не в тему. И ну и явно ты не разобрался с темой. S>>Почитай https://pvs-studio.com/ru/b/0808/#ID4EFF844D56
I>Разобрался примерно в 2003м году на корутинах Питона, а в 2008 нашел в С# yield
Ну тогда за что минус!!
и солнце б утром не вставало, когда бы не было меня
Re[37]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
I>>>Linq основан на IQueryable, а IEnumerable нужн рассматривать как оптимизацию частного случая. S>>И откуда ты ото взял. При этом бОльшая часть линка используется именно для IEnumerable. S>>Деревья выражений не используются в IEnumerable, но ты не против них!
I>Деревья нужны что бы строить скажем SQL. Добавил пров — получил итерацию. I>С IEnumerable так невозможно.
Можно!! Берем Roslyn и обрабатываем! Нет проблем S>> Еще раз List реализует IEnumerable, но заполнение List ну ни хрена не ленива!!
I>Когда тебе надо по одному источнику проходить несколько раз, что вобщем частый случай, издержки от yield и тотальной ленивости возрастают до небес.
Linq это цепочка вызовов в 5 и более расширений и по этому ленивость важна, что бы свести количество итераций к минимуму.
Именно на этом и посмтроен линк для коллекций. И ты мне за это ставишь минус!!!
То есть те кто использует Linq для коллекций дураки и нужно использовать List S>>Или другие способы генерации кода например Source Generator S>>https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/
I>На всякий — я портировал часть Linq и ODATA на JavaScript. Просто что бы ты представлял, откуда у меня познания в Linq и его применениях.
Я рад за тебя. Зачем ты портировал если он такой плохой. ODATA вообще то не имеет отношения к Linq. 1C использует, но линка в нем нет
Но есть Linq to ODATA но там IQueriable
И в итоге за что минус!!!
и солнце б утром не вставало, когда бы не было меня
I>Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог. I>Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание.
var results = items.Where(i => i % 10 == 0)
.Select(i => i + 5);
Первый твой любимый List
IEnumerable<int> LinqOptimizer(int [] input)
{
var collector = new Nessos.LinqOptimizer.Core.ArrayCollector<int>();
for (int counter = 0; counter < input.Length; counter++)
{
var i = input[counter];
if (i % 10 == 0)
{
var result = i + 5;
collector.Add(result);
}
}
return collector;
}
Второй с использованием yield
IEnumerable<int> RoslynLinqRewriteWhereSelect_ProceduralLinq1(int[] _linqitems)
{
if (_linqitems == null)
throw new System.ArgumentNullException();
for (int _index = 0; _index < _linqitems.Length; _index++)
{
var _linqitem = _linqitems[_index];
if (_linqitem % 10 == 0)
{
var _linqitem1 = _linqitem + 5;
yield return _linqitem1;
}
}
}
И вычиление результата.
var counter = 0;
foreach (var result in results)
{
counter += result;
}
return counter;
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, Serginio1, Вы писали:
S>>Спасибо Интересно не знал, что SQL синтаксис может работать не только с IEnumerable.
НС>Через 15 лет после появления линка?
Ну да. Вернее то, что вызывается SelectMany. Потому, что им напрямую и не пользовался!
Зато честно признался!
и солнце б утром не вставало, когда бы не было меня
Re[26]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
НС>>Через 15 лет после появления линка? S> Ну да. Вернее то, что вызывается SelectMany. Потому, что им напрямую и не пользовался!
Фейспалм был касательно того, что ты тут о каких то тонкостях несколько дней выспоряешь, а сам при этом не знаешь совсем уж базовых вещей.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[38]: Есть ли подобие LINQ на других языках/платформах?
Ты хочешь что бы я каждый раз сверял одни твои слова с другим твоими словами?
I>>Вместо yield a пишем observer.next(a) S> Приведи реальный код. Заметь я тебе даю кучу ссылок но ты их и не читаешь и дальше плетешь всякую хрень.
Ты путаешь AsyncEnumerable и обычный RX Observable.
AsyncEnumerable это pull-модель. RX — push, и это Observable. AsyncEnumerable это недавнее расширение, я про него ничего не говорю.
Алё! Ты показываешь другую либу!!!!!!!!!!!!!!!!!!!!
Смотри на урл свой — у тебя Ix.NET — Ix.NET/Source/System.Linq.Async
Ты чё, реально недогоняешь, что это совсем другой механизм?
Итого — с учето вызываемых функций — ровно то же.
I>>Это не важно, что от чего наследуется. При помощи IQueryable можно сделать всё, добавляя провайдер. I>>С IEnumerable так не получится.
S> То есть минус ты мне поставил за то, что IEnumerable так не может при работе с БД, поэтому yield отстой и он не нужен и без него Linq и без него линк прекрасно обходится! S>За что минус!!!!
За то, что ты приписываешь мне слова "yield — отстой" и никак не можешь этого заметить.
yield как и любой инструмент имеет границы применения. Внутри границ — идеален, вне границ — не годится.
Вот и всё.
А для тебя, похоже, сам факт существования границ применимости лично тебя оскорбляет
Re[39]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
I>>Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог. I>>Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание.
S> Я уже приводил тебе на замеры производительности. Прочитай еще раз S>https://mattwarren.org/2016/09/29/Optimising-LINQ/
Это синтетический тест, который замеряет какой то очень крохотный кейс. Я точно так же напишу другой, вида while(true) { yield i++}, пройдусь по ём сотню раз от нуля до миллиона и мы увидим, что в тысячу раз хуже и по памяти и процессору обычного цикла безо всяких массиво.
S> есть простейший запрос и оптимизаторы S>
S>var results = items.Where(i => i % 10 == 0)
S> .Select(i => i + 5);
S>
Я не сильно понимаю эти результаты. Что такое удавы и какой код получил 3 удава? Самый быстрый это 3 или 5 ?
S> То есть твои доводы про производительность yield идут лесом.
Я вижу, что здесь непойми что и не ясно, зачем вообще выделять память. Зачем делать add() если можно просто вызвать соответствующую функцию?
Память нужно выделять в том случае, если у нас есть многочисленные повторные проходы по источнику.
То есть, если ты сотню раз будешь использовать источник такого вида
while(true) {
yield i++;
}
То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее.
И для оптимизации используется кеширование коллекции.
Re[38]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
S>>>Деревья выражений не используются в IEnumerable, но ты не против них!
I>>Деревья нужны что бы строить скажем SQL. Добавил пров — получил итерацию. I>>С IEnumerable так невозможно. S> Можно!! Берем Roslyn и обрабатываем! Нет проблем
Какой проблемы нету? У тебя есть экземпляр IEnumerable, куда мы натыкали кучу фильтров и проекций из разных мест приложения — плагины, конфигурация, юзеринпут и запросы от клиента.
Какой код нужно написать, что бы построить по этому экземпляру правильный SQL, что бы отдать его базе данных?
I>>Когда тебе надо по одному источнику проходить несколько раз, что вобщем частый случай, издержки от yield и тотальной ленивости возрастают до небес. S>Linq это цепочка вызовов в 5 и более расширений и по этому ленивость важна, что бы свести количество итераций к минимуму.
Вот, смотри — где здесь лишние итерации и лишнее выделение памяти:
let state = initial();
let i = 0;
while(true) {
i++;
state = state.next(i);
if(isGoodEnough(state, i)) {
return {state, i};
}
}
Покажи пальцем, где здесь "инициализация List всегда неленивая!!!!!!1111"
S>Именно на этом и посмтроен линк для коллекций. И ты мне за это ставишь минус!!!
Очевидно — не за это.
S>То есть те кто использует Linq для коллекций дураки и нужно использовать List
Минусы — за подобные утверждения. Ты приписываешь мне бред который в твоей собственной голове.
I>>На всякий — я портировал часть Linq и ODATA на JavaScript. Просто что бы ты представлял, откуда у меня познания в Linq и его применениях. S>Я рад за тебя. Зачем ты портировал если он такой плохой.
А я нигде не говорю, что он плохой. Это ты сам додумываешь, и интерпретируешь таким вот образом.
> ODATA вообще то не имеет отношения к Linq.
То есть, ты не в курсе, что ODATA построена на linq ?
> 1C использует, но линка в нем нет. Но есть Linq to ODATA но там IQueriable
Читаем твою же ссылку:
То есть можно работать с ODATA полностью на Linq
S>И в итоге за что минус!!!
В т.ч. за то, что пишешь, не имея представления. Немного ликбеза, ODATA это SQL over HTTP, и вот как это работает
var result = (from Тестовый in context.Catalog_Тестовый
where Тестовый.Ref_Key == new Guid("aada18ad-5308-11e5-8e05-c86000c70663")
select Тестовый).SingleOrDefault();
По этой хрени мы, точнее linq odata provider, используя Expression, построит запрос примерно такого вида
GET /Catalog_Тестовый?
$filter=Ref_Key eq aada18ad-5308-11e5-8e05-c86000c70663
&$select=Тестовый
&$top=1
Далее, сервер всё это распарсит, построит по этому запросу Expression, который, в свою очередь, передаём в Linq пров типа linq2db и он вернёт нам данные.
Далее, odata фремворк получает данные, серилизует их и отправляет клиенту.
Re[38]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Serginio1, Вы писали:
S>Ты совсем не читаешь. Издеваешься. Ленивость это когда код начинается вызваться не до создания итератора, а после его создания. S>https://rsdn.org/article/csharp/CSharp_Iterators.xml
S>Можно сказать, что каждый блок кода, между операторами yield return выполняется отложенно (lazily) только после очередного вызова метода MoveNext. Именно на этом основана ленивость библиотеки LINQ, которая построена в виде методов расширения интерфейсов IEnumerable и IEnumerable<T>.
Ты сам то пробовал итераторы реализовывать? В итераторе до вызова MoveNext вообще ничего не происходит, хоть с yield, хоть без него.
S> Тебе обязательно нужно поставить минус!!!!
Именно, потому как ты не в курсе, как работает обычный итератор, который насквозь ленивый даже без yield.
I>>>>Четвертый раз — вместо x[i] у тебя MoveNext, проход через switch, присваивание Current и чтение Current I>>>>И вот эта каша крайне плохо инлайнится, а следовательно ест больше чем весит. I>>>>Заметь — это уже в четвертый раз я пишу, а до тебя не доходит.
S> Ты издеваешься? Я тебе привожу ссылки где написано, что ленивости там никакой нет.
Какой ленивости нет в обычном итераторе? До вызова MoveNext у тебя ничего не выполняется.
То есть
const iterator = new CoolIterator(); // уп, нет того списка, который якобы надо создать :-)
// вот здесь у нас отработал только конструктор итератора, и ничего больше. Никакого копирования данных, вообще ничего нет.
iterator.MoveNext() // вот здесь обработали первую порцию данных. Ровно одну, и ничего больше.
И так всегда, независимо от того, как мы получили CoolIterator — через yield, или написали руками.
S>Ты должен доказать, что товарищ не прав!
Именно. Ты не в курсе, как работает итератор и почему он сам по себе ленивй и был ленивым во все времена до введения yield.
Все, что делает yield, это генерирует итератор. Но это не добавляет ленивости, только уменьшает количество кода.
I>>А ты, упорный. Раз я с тобой не согласен, значит — против yield S>Минус за что!
За то, что пишешь ересь. Покажи, где тут список, который создаётся:
public class CoolIterator : IEnumerator
{
int i = 0;
public CoolIterator()
{
_people = list;
}
public bool MoveNext()
{
i++;
return true;
}
public void Reset()
{
i = 0;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public Person Current
{
get
{
return i;
}
}
}
Валяй, ищи список.
I>> Что значит "ленивое создание итераторов" ? Он и до введения yield создавался только по требованию, т.е. ленивым образом. А сам итератор и без тебя ленивый. S>List создается то того как дергается его MoveNext, и дергает родительский MoveNext!!!
Это совсем не обязательно. Никакого list может и не быть. Смотри пример.
I>>Нет, не понятно. Итератор сам по себе ленивый, и так было до yield. И создавался ленивым образом, тоже до yield. S>Дааааа. То есть ты про List так и не ответил.
Раскрой глаза — какой еще лист? Если мне зачем то понадобился итератор, это совсем необязательно значит, что и какой то лист или массив есть.
Может — да, может — нет.
I>>Так было и до введения yield. Это бенефиты IEnumerable, они работают и без yield. S> Еще раз List это IEnumerable но он нихрена не ленив.
Я выше привел пример кода, покажи где там недостаток ленивости
I>>Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог. I>>Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание. S>То есть выполнить 5 создания классов, вызов лямбд будет больше чем миллионы вызовов [x] лямбд и селектов.
Не надо фантазий.
Есть алгоритм в котором if(x[0] == pattern) {return} ; выполняется много раз.
А это значит, что ты предлагаешь x[0] заменить на кучу приседаний через yield, т.е. if(x.First() == pattern) {return}
То есть, в чистом виде замедление.
Когда это становится узким местом — нужно выбросить linq.
I>>Не смеши людей. Я портировал часть Linq и ODATA на JavaScript, а что сделал ты ? S> Ну ты молодец!! Я так херню всякую пишу и тебе в подметки не гожусь.
Не в курсе, на что ты годишься, но ты даже не понимаешь, что ODATA в дотнете что на клиенте, что на сервере работает через Linq.
I>>А зачем мне list если мне нужна только итерация? Создаем итератор, итерируемся, пока это нужно, профит. Все что надо — один класс создаём явно. yield — делает ровно то же, но не явно. Вся разница. И ленивости в каждом случае ровно одинаково. S> Какой итератор ты создаешь? List тоже итератор
Я привел пример кода
I>>Разобрался примерно в 2003м году на корутинах Питона, а в 2008 нашел в С# yield S>Ну тогда за что минус!!
За то, что ересь пишешь.
Re[40]: Есть ли подобие LINQ на других языках/платформах?
Я могу написать другой тест, который провалит замеры против массива во сколько угодно раз.
Речь то не идет о том, плох linq или хорош, а о том, когда и где хорошо справляется, а когда и где есть вещи получше.
Я уверен, ты не понимаешь фразу выше. Ну не понимаешь и всё. Особенность у тебя такая. Попроси может кого, что бы объяснили, что это значит с т.з. русского языка.
Re[39]: Есть ли подобие LINQ на других языках/платформах?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, Ikemefula, Вы писали:
I>>>Именно. x[0] инлайнится враз и стоит считай бесплатно. А x.FirstOrDefault() в сравнении с этим неимоверно дорог. I>>>Например, когда эта операция одна из основных в экспоненциальном алгоритме, любая издержка дает конское отставание.
S>> Я уже приводил тебе на замеры производительности. Прочитай еще раз S>>https://mattwarren.org/2016/09/29/Optimising-LINQ/
I>Это синтетический тест, который замеряет какой то очень крохотный кейс. Я точно так же напишу другой, вида while(true) { yield i++}, пройдусь по ём сотню раз от нуля до миллиона и мы увидим, что в тысячу раз хуже и по памяти и процессору обычного цикла безо всяких массиво.
I>
S>> есть простейший запрос и оптимизаторы S>>
S>>var results = items.Where(i => i % 10 == 0)
S>> .Select(i => i + 5);
S>>
S>> Итеративно 3 удава S>> Linq 4.88 S>> Roslyn 3.87 S>> LinqOptimiser 5.03
I>Я не сильно понимаю эти результаты. Что такое удавы и какой код получил 3 удава? Самый быстрый это 3 или 5 ?
Ну посмотри статью. Там все написано и расписано.
S>> То есть твои доводы про производительность yield идут лесом.
I>Я вижу, что здесь непойми что и не ясно, зачем вообще выделять память. Зачем делать add() если можно просто вызвать соответствующую функцию? I>Память нужно выделять в том случае, если у нас есть многочисленные повторные проходы по источнику.
В том, что нужно получать итератор. А здесь как раз идет сравнение с итератора и через прямое вычисление без итераторов.
Так или иначе идет вызов MoveNext на стороне итератора идут 10 вызовов кстати через индекс так как передан массив.
Но нужны коллекции для заиси в базу, отображения итд
I>То есть, если ты сотню раз будешь использовать источник такого вида I>
I>while(true) {
I> yield i++;
I>}
I>
I>То ты сэкономишь кучу памяти, но при этом работа с источником окажется примерно в 1000 раз медленнее. I>И для оптимизации используется кеширование коллекции.
В реалии Отборов может быть великое множество. Памяти не хватит кэшировать.
Мало того данные имеют свойство меняться
if (_linqitem % 10 == 0)
{
var _linqitem1 = _linqitem + 5;
yield return _linqitem1;
}
3 попугая для
public int Iterative()
{
var counter = 0;
foreach (var item in items)
{
if (item % 10 == 0)
counter += item;
}
return counter;
}
и 3.8 для
IEnumerable<int> results = compiledWhereSelectQuery(items);
var counter = 0;
foreach (var result in results)
{
counter += result;
}
то есть 0.8 секунды уходит на итератор. Учитывая что реально вызывается только каждый 10.
Можно умножить на 10 итого 8 попугая
то есть в самом писсимистичном это будет 11 попугая 11/3 максимум в 4 раза.
Но когда нам нужны коллекции заполнение List оказывается значительно дороже.
То есть вычисления слева на право себя не оправдывают
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Serginio1, Вы писали:
S>>Все это словоблудие. Вот реальные замеры производительности S>>http://rsdn.org/forum/flame.comp/7995827.1
I>Я могу написать другой тест, который провалит замеры против массива во сколько угодно раз.
I>Речь то не идет о том, плох linq или хорош, а о том, когда и где хорошо справляется, а когда и где есть вещи получше.
I>Я уверен, ты не понимаешь фразу выше. Ну не понимаешь и всё. Особенность у тебя такая. Попроси может кого, что бы объяснили, что это значит с т.з. русского языка.
Вот напиши и покажи.
И обоснуй минус!
и солнце б утром не вставало, когда бы не было меня