Сообщение Re[39]: 2D-Linq и оптимизация цифровых фильтров - 3 от 11.07.2018 10:24
Изменено 11.07.2018 10:29 vdimas
Re[39]: 2D-Linq и оптимизация цифровых фильтров - 3
Здравствуйте, Sinclair, Вы писали:
V>>Я ХЗ как можно было убить на это столько времени и не выйти на простую абстракцию, примеры которых я показал, назвав их "индексерами"?
S>
S>Эта абстракция мне неинтересна ровно потому, что не позволяет сократить запись прикладных алгоритмов и сделать их более понятными.
Ты спрятал важную подробность алгоритма.
Причём, за нечитаемым кодом.
S>Мне интересна ровно обратная сторона — записать алгоритм так, чтобы скрыть несущественные подробности.
Т.е., ты, таки, прямым текстом расписываешься в собственной необъективности? ))
ОК, так и запишем: разрабатывать эффективные хелперы для обхода двумерных массивов Синклер согласен только для Linq и ни боже упаси для чего-то "другого".
V>>Думаешь, твоё решение читабельней? ))
S>А что тут думать? Я же его привёл.
Нечитабельно.
S>Там одна строчка — меньше уже некуда.
Одна строчка описывает только часть алгоритма, а не целиком его.
Целиком вышло кошмарно.
S>Сколько строчек в вашей реализации самого эффективного c4?
Полностью если? Намного меньше, чем в твоём полном решении.
Мои строчки читабельные и поддерживаемые.
Твои — категорически нет.
V>>"Лапша" тут может быть лишь от попыток свалить все части алгоритма в один цикл.
S>Ну вы же именно это и предложили.
И опять соврал.
Я пока не предлагал ничего, кроме как сделать сравнение честным, т.е. если уж оптимизируется доступ к двумерному массиву, то пусть он оптимизируется для ВСЕХ сравниваемых техник.
S>И даже хвастаетесь — как раз тем, что детали обработки краёв у вас в том же алгоритме.
Но не в том же цикле.
Я ХЗ как можно оставлять процитированное мною, при этом приписывая мне ровно противоположное тому, что я говорил.
Выглядит так, что ты опять и снова запаниковал, бо тут уже запахло сравнением реализации ПОЛНОГО алгоритма, а не упрощенного.
Т.е. когда требуется обработать краевые эффекты согласно некоторому параметру (через заданный цвет бесконечности или через расширение картинки за счёт крайних пикселей).
V>>Разбей алгоритм на несколько частей:
V>>- безопасное, максимально эффективное тело без краевых эффектов;
V>>- проход по краевым эффектам.
S>Совершенно верно.
Ну и где у тебя ограничение прохода лишь по безопасной области массива?
Где и как это выражено?
Ткни пальцем в участок своего кода, если я что-то упустил.
V>>Отрасль с этим Linq подробно разобралась еще лет 10 назад.
S>Вы представляете прекрасный контрпример этому утверждению.
Мы?
Ты пока показал, что и близко Linq еще не нюхал, бо даже не понимаешь, о каких граблях тебе говорят. ))
V>>Ты начни туда прикручивать where, например, сделать c4 только для абсолютно чёрных точек.
S>И в чём проблема? Вы не понимаете, как работает where clause, или что?
Я понимаю как работает перегрузка методов-расширений, поэтому и предлагаю, таки, окунуться чуть поближе, а потом уже делать выводы.
V>>Или сделай из изображения последовательность центральных точек по Вороному.
V>>Помнишь я говорил тебе о конфликте сигнатур?
V>>Похоже ты так и не понял этого замечания. ))
S>Не, не понял. Какая сигнатура и с чем будет конфликтовать?
Ну так ты начни делать и увидишь.
А я рядом пример уже приводил.
Просто пока у тебя в сигнатурах не появилось Select<T, TResult, TCollection>(this TCollection, ...) where TCollection : ISomeInterface<T> — никакой проблемы нет, разумеется.
Обойти это можно только через ConcreteCollection2<TResult> Select<T, TResult>(this ConcreteCollection1<T>, ...), где ConcreteCollection1 — эдакие value-type обертки-маркеры. Но начав покрывать сценарии из обсуждаемой предметной области ты быстро обнаружишь резкий рост комбинаторики на ровном месте. В "стандартном" линке типы стираются через боксинг, но мы-то хотим его избежать, верно?
Кароч, пока сам не попробуешь, так и будешь не понимать о чём речь.
V>>Так вот, "заняв" целиком и полностью сигнатуру Select реализацией с активным возвратом результата, ты обрубил целый пласт алгоритмов.
S>Ну и кто из нас тут демонстрирует непонимание?
Ты, разумеется.
S>Я привёл маленький, короткий proof of concept.
А тебе отвечают люди, которые их делали в количестве за все эти годы.
Просто делятся опытом — с чем пришлось столкнуться и почему так.
И заодно объясняют — почему ты не столкнулся.
Из-за размерности твоего примера.
S>Просто потому, что для форумных обсуждений я не могу потратитьcz на написание полноценного стека с поддержкой всех девяти конструкций query comprehension.
Без боксинга если, то вовсе не 9-ти.
Может я и не прав, что сразу не раскрыл эту часть своих возражений, но до прошлого сообщения я не представлял, насколько ты не в курсе вопроса.
Наивно считал, что простого напоминания о граблях будет достаточно.
S>В реальной промышленной библиотеке конечно же будет возвращаться не T[,], а promise, который будет резолвиться либо явно через .ToArray() либо неявно через вызов [,].
S>Конечно же будет строиться вся цепочка операций.
Ага.
Только у value-типов никаким образом не стираются типы.
S>>>Б) красота линка вовсе не обязательно связана с performance penalty. Внезапно оказывается, что он ещё и быстрее "идиоматического" кода.
V>>Это ложь. Он не быстрее.
S>Бенчмарки утверждают обратное.
Бенчмарки левые, измеряют шумовые эффекты, а не эффективность линка.
Поставь бенчмарки в одинаковые условия, исключи наведённые помехи и измерь снова.
А до тех пор будешь носить клеймо необъективного человека.
V>>Что помешало тебе применить все свои трюки к "идиоматическому" коду, чтобы сравнение вышло спортивным?
S>То, что код с unsafe и манипуляциями указателями не является "идиоматическим".
Сейчас уже можно без unsafe:
Пока оно немного уступает unsafe по эффективности, но обещается, что будет то же самое.
S>Естественно, я эти трюки применил первым же делом — я же сначала написал идеальную версию на С#, и уже потом подсмотрел, какой MSIL надо сгенерировать.
S>Моя задача была дать возможность эти трюки использовать повторно.
S>В вашем подходе код c4 — это двадцать строк; код с8 — ещё 20 строк; код циклического сдвига — ещё 15.
S>А в моём каждый из них — это одна строка.
В показанном тобой коде это не так.
S>Не надо каждый раз считать единички, проверять, куда там сползают указатели, и прочее. Гарантии корректности без потери производительности.
Дык, ты как раз пренебрег гарантиями корректности. ))
Похоже, ты в "гарантии" отнёс только защиту от выхода за границы массива, но пренебрег корректностью алгоритма.
Но в этом случае твоём решение решением НЕ является.
V>>Без конфликтов сигнатур?
S>Ага
Так ты приступи уже, потом приходи, поговорим.
V>>В ответ справедливые технические замечания, на которые у тебя истерика.
S>Технических замечаний нет. Ну не считать же таким, в самом деле, комментарий про использование T[,]. При том, что Array2d всё равно, какой там внутри массив — переписывание на struct FastArray по мотивам вашего индексера заняло 15 минут и не дало никакой (естественно) разницы.
Пипец.
Разница не у тебя должна была появиться, а у "идиоматического" кода.
V>>Подмена задачи случилась у тебя.
V>>А я лишь вытащил на свет божий всё это грязное бельё с подменой задачи. ))
S>Простите, коллега, но вы разговариваете с голосами в своей голове. Я задачу как сформулировал, так и решил.
1. Пока что ты её не решил целиком.
2. В твоей формулировке не утверждалось, что идиоматический код не может пользоваться хелперами.
Хотя в реальных алгоритмах обработки изображений (на тех же плюсах) весь "идиматический" код (т.е. написанный в виде явного итерирования) — он всегда работает поверх неких аналогов показанных мною "индексеров". Потому что по-другому в этой предметной области никак, бо форматов/кодировок даже RAW-изображений слишком много.
Не веришь — спроси у Вольфхаунда, он одно время, вроде бы, занимался такими вещами плотно. ))
V>>Это ведь ты подменил эксперимент по оценке скорости работы линка на эксперимент по ускорению доступа к двумерному массиву.
S>Ну конечно же нет. Задача стояла ровно наоборот — исследовать возможность использования linq для 2d-фильтрации, и возможности не просадить при этом производительность.
В показанном тобой виде возможность отсутствует как класс. Задача не решена. Итоговые пиксели подсчитаны неверно.
Т.е., я пока не увидел в твоём коде ничего помимо трюка с ускорением обхода массива.
Поэтому, я как честный человек, могу обсуждать лишь ту часть задачи, которую тебе удалось решить на данный момент.
Всё остальное от тебя — это лишь обещания "прекрасного будущего", какие мы слышали от тебя же еще с 2003-2004-х годов. ))
Просто мне есть чем возразить — никакого прекрасного будущего там не будет.
Проблематику дизайна линка я подробно расковырял еще хрен его знает когда.
Потому что злоупотребляю value-типами в своих разработках на донете.
Когда/если ты попытаешься окучить всю комбинаторику сценариев, пытаясь при этом избежать боксинга — ты сам всё увидишь.
Пока же тебе удалось (впервые в жизни, судя по уровню радости) написать метод-расширение под линк и тебя банально понесло, ты забыл быть объективным.
V>>Что тебе не понятно во фразе "ограничения генериков не входят в сигнатуры генерик-типов и методов"?
S>Непонятно, почему вы решили, что это помешает в рассматриваемой задаче. Пока что у меня всё получается
Потому что ты подаешь на вход абстрактный ref-тип, которым является массив.
А даже если пробовал Array2d, то максимум в одном сценарии, т.е. еще не нарвался на каскадные Select.
V>>Если придуряешься, то можешь считать себя клоуном.
S> V>Если действительно не понял, то трус и форумный хамло, который вместо простого "я тут недопонял" маскирует своё непонимание через нападки, нимало не смущаясь тем, что увеличивает градус нервозности. Со стороны не пробовал на такие закидоны смотреть? ))
S>Вот, коллега, вот это — переходы на личности. Я свой сарказм проявляю по отношению к вашим аргументам, а не к вашим личным достоинствам или недостаткам.
Жалкая отмазка, однако.
Тут всё-таки взрослые дяди, т.е. без подсказок вкурсе сотен способов сообщить человеку, что он дурак каким-нить "косвенным" образом, навроде "так рассуждают только дураки".
Кароч, детсад, первая четверть.
И при этом твой фирменный стиль.
Который рано или поздно задалбывает, ес-но.
S>Давайте мы в следующий раз всё-таки выпишем вам бан дней на 120, ок?
Давай ты в следующий раз не будешь поднимать градус нервозности по собственной инициативе.
Бери пример с меня — я принципиально отвечаю в подобном ключе только в ответ.
И то, первые пару раз почти всегда игнорю — даю возможность "одуматься".
Неплоха стратегия, рекомендую.
Некому начинать — некому продолжать, очевидно ж.
V>>Я ХЗ как можно было убить на это столько времени и не выйти на простую абстракцию, примеры которых я показал, назвав их "индексерами"?
S>
S>Эта абстракция мне неинтересна ровно потому, что не позволяет сократить запись прикладных алгоритмов и сделать их более понятными.
Ты спрятал важную подробность алгоритма.
Причём, за нечитаемым кодом.
S>Мне интересна ровно обратная сторона — записать алгоритм так, чтобы скрыть несущественные подробности.
Т.е., ты, таки, прямым текстом расписываешься в собственной необъективности? ))
ОК, так и запишем: разрабатывать эффективные хелперы для обхода двумерных массивов Синклер согласен только для Linq и ни боже упаси для чего-то "другого".
V>>Думаешь, твоё решение читабельней? ))
S>А что тут думать? Я же его привёл.
Нечитабельно.
S>Там одна строчка — меньше уже некуда.
Одна строчка описывает только часть алгоритма, а не целиком его.
Целиком вышло кошмарно.
S>Сколько строчек в вашей реализации самого эффективного c4?
Полностью если? Намного меньше, чем в твоём полном решении.
Мои строчки читабельные и поддерживаемые.
Твои — категорически нет.
V>>"Лапша" тут может быть лишь от попыток свалить все части алгоритма в один цикл.
S>Ну вы же именно это и предложили.
И опять соврал.
Я пока не предлагал ничего, кроме как сделать сравнение честным, т.е. если уж оптимизируется доступ к двумерному массиву, то пусть он оптимизируется для ВСЕХ сравниваемых техник.
S>И даже хвастаетесь — как раз тем, что детали обработки краёв у вас в том же алгоритме.
Но не в том же цикле.
Я ХЗ как можно оставлять процитированное мною, при этом приписывая мне ровно противоположное тому, что я говорил.
Выглядит так, что ты опять и снова запаниковал, бо тут уже запахло сравнением реализации ПОЛНОГО алгоритма, а не упрощенного.
Т.е. когда требуется обработать краевые эффекты согласно некоторому параметру (через заданный цвет бесконечности или через расширение картинки за счёт крайних пикселей).
V>>Разбей алгоритм на несколько частей:
V>>- безопасное, максимально эффективное тело без краевых эффектов;
V>>- проход по краевым эффектам.
S>Совершенно верно.
Ну и где у тебя ограничение прохода лишь по безопасной области массива?
Где и как это выражено?
Ткни пальцем в участок своего кода, если я что-то упустил.
V>>Отрасль с этим Linq подробно разобралась еще лет 10 назад.
S>Вы представляете прекрасный контрпример этому утверждению.
Мы?
Ты пока показал, что и близко Linq еще не нюхал, бо даже не понимаешь, о каких граблях тебе говорят. ))
V>>Ты начни туда прикручивать where, например, сделать c4 только для абсолютно чёрных точек.
S>И в чём проблема? Вы не понимаете, как работает where clause, или что?
Я понимаю как работает перегрузка методов-расширений, поэтому и предлагаю, таки, окунуться чуть поближе, а потом уже делать выводы.
V>>Или сделай из изображения последовательность центральных точек по Вороному.
V>>Помнишь я говорил тебе о конфликте сигнатур?
V>>Похоже ты так и не понял этого замечания. ))
S>Не, не понял. Какая сигнатура и с чем будет конфликтовать?
Ну так ты начни делать и увидишь.
А я рядом пример уже приводил.
Просто пока у тебя в сигнатурах не появилось Select<T, TResult, TCollection>(this TCollection, ...) where TCollection : ISomeInterface<T> — никакой проблемы нет, разумеется.
Обойти это можно только через ConcreteCollection2<TResult> Select<T, TResult>(this ConcreteCollection1<T>, ...), где ConcreteCollection1 — эдакие value-type обертки-маркеры. Но начав покрывать сценарии из обсуждаемой предметной области ты быстро обнаружишь резкий рост комбинаторики на ровном месте. В "стандартном" линке типы стираются через боксинг, но мы-то хотим его избежать, верно?
Кароч, пока сам не попробуешь, так и будешь не понимать о чём речь.
V>>Так вот, "заняв" целиком и полностью сигнатуру Select реализацией с активным возвратом результата, ты обрубил целый пласт алгоритмов.
S>Ну и кто из нас тут демонстрирует непонимание?
Ты, разумеется.
S>Я привёл маленький, короткий proof of concept.
А тебе отвечают люди, которые их делали в количестве за все эти годы.
Просто делятся опытом — с чем пришлось столкнуться и почему так.
И заодно объясняют — почему ты не столкнулся.
Из-за размерности твоего примера.
S>Просто потому, что для форумных обсуждений я не могу потратитьcz на написание полноценного стека с поддержкой всех девяти конструкций query comprehension.
Без боксинга если, то вовсе не 9-ти.
Может я и не прав, что сразу не раскрыл эту часть своих возражений, но до прошлого сообщения я не представлял, насколько ты не в курсе вопроса.
Наивно считал, что простого напоминания о граблях будет достаточно.
S>В реальной промышленной библиотеке конечно же будет возвращаться не T[,], а promise, который будет резолвиться либо явно через .ToArray() либо неявно через вызов [,].
S>Конечно же будет строиться вся цепочка операций.
Ага.
Только у value-типов никаким образом не стираются типы.
S>>>Б) красота линка вовсе не обязательно связана с performance penalty. Внезапно оказывается, что он ещё и быстрее "идиоматического" кода.
V>>Это ложь. Он не быстрее.
S>Бенчмарки утверждают обратное.
Бенчмарки левые, измеряют шумовые эффекты, а не эффективность линка.
Поставь бенчмарки в одинаковые условия, исключи наведённые помехи и измерь снова.
А до тех пор будешь носить клеймо необъективного человека.
V>>Что помешало тебе применить все свои трюки к "идиоматическому" коду, чтобы сравнение вышло спортивным?
S>То, что код с unsafe и манипуляциями указателями не является "идиоматическим".
Сейчас уже можно без unsafe:
[StructLayout(LayoutKind.Sequential, Pack =1)]
public struct Rgb24 {
public byte R;
public byte G;
public byte B;
public Rgb24(byte r, byte g, byte b) {
R = r;
G = g;
B = b;
}
}
class Program {
static void Main(string[] args) {
Rgb24[,] image = {
{ new Rgb24(1, 2, 3), new Rgb24(4, 5, 6) },
{ new Rgb24(7, 8, 9), new Rgb24(10, 11, 12) }
};
var bytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref image[0, 0], image.Length));
foreach(byte b in bytes)
Console.WriteLine(b);
}
}
Пока оно немного уступает unsafe по эффективности, но обещается, что будет то же самое.
S>Естественно, я эти трюки применил первым же делом — я же сначала написал идеальную версию на С#, и уже потом подсмотрел, какой MSIL надо сгенерировать.
S>Моя задача была дать возможность эти трюки использовать повторно.
S>В вашем подходе код c4 — это двадцать строк; код с8 — ещё 20 строк; код циклического сдвига — ещё 15.
S>А в моём каждый из них — это одна строка.
В показанном тобой коде это не так.
S>Не надо каждый раз считать единички, проверять, куда там сползают указатели, и прочее. Гарантии корректности без потери производительности.
Дык, ты как раз пренебрег гарантиями корректности. ))
Похоже, ты в "гарантии" отнёс только защиту от выхода за границы массива, но пренебрег корректностью алгоритма.
Но в этом случае твоём решение решением НЕ является.
V>>Без конфликтов сигнатур?
S>Ага
Так ты приступи уже, потом приходи, поговорим.
V>>В ответ справедливые технические замечания, на которые у тебя истерика.
S>Технических замечаний нет. Ну не считать же таким, в самом деле, комментарий про использование T[,]. При том, что Array2d всё равно, какой там внутри массив — переписывание на struct FastArray по мотивам вашего индексера заняло 15 минут и не дало никакой (естественно) разницы.
Пипец.
Разница не у тебя должна была появиться, а у "идиоматического" кода.
V>>Подмена задачи случилась у тебя.
V>>А я лишь вытащил на свет божий всё это грязное бельё с подменой задачи. ))
S>Простите, коллега, но вы разговариваете с голосами в своей голове. Я задачу как сформулировал, так и решил.
1. Пока что ты её не решил целиком.
2. В твоей формулировке не утверждалось, что идиоматический код не может пользоваться хелперами.
Хотя в реальных алгоритмах обработки изображений (на тех же плюсах) весь "идиматический" код (т.е. написанный в виде явного итерирования) — он всегда работает поверх неких аналогов показанных мною "индексеров". Потому что по-другому в этой предметной области никак, бо форматов/кодировок даже RAW-изображений слишком много.
Не веришь — спроси у Вольфхаунда, он одно время, вроде бы, занимался такими вещами плотно. ))
V>>Это ведь ты подменил эксперимент по оценке скорости работы линка на эксперимент по ускорению доступа к двумерному массиву.
S>Ну конечно же нет. Задача стояла ровно наоборот — исследовать возможность использования linq для 2d-фильтрации, и возможности не просадить при этом производительность.
В показанном тобой виде возможность отсутствует как класс. Задача не решена. Итоговые пиксели подсчитаны неверно.
Т.е., я пока не увидел в твоём коде ничего помимо трюка с ускорением обхода массива.
Поэтому, я как честный человек, могу обсуждать лишь ту часть задачи, которую тебе удалось решить на данный момент.
Всё остальное от тебя — это лишь обещания "прекрасного будущего", какие мы слышали от тебя же еще с 2003-2004-х годов. ))
Просто мне есть чем возразить — никакого прекрасного будущего там не будет.
Проблематику дизайна линка я подробно расковырял еще хрен его знает когда.
Потому что злоупотребляю value-типами в своих разработках на донете.
Когда/если ты попытаешься окучить всю комбинаторику сценариев, пытаясь при этом избежать боксинга — ты сам всё увидишь.
Пока же тебе удалось (впервые в жизни, судя по уровню радости) написать метод-расширение под линк и тебя банально понесло, ты забыл быть объективным.
V>>Что тебе не понятно во фразе "ограничения генериков не входят в сигнатуры генерик-типов и методов"?
S>Непонятно, почему вы решили, что это помешает в рассматриваемой задаче. Пока что у меня всё получается
Потому что ты подаешь на вход абстрактный ref-тип, которым является массив.
А даже если пробовал Array2d, то максимум в одном сценарии, т.е. еще не нарвался на каскадные Select.
V>>Если придуряешься, то можешь считать себя клоуном.
S> V>Если действительно не понял, то трус и форумный хамло, который вместо простого "я тут недопонял" маскирует своё непонимание через нападки, нимало не смущаясь тем, что увеличивает градус нервозности. Со стороны не пробовал на такие закидоны смотреть? ))
S>Вот, коллега, вот это — переходы на личности. Я свой сарказм проявляю по отношению к вашим аргументам, а не к вашим личным достоинствам или недостаткам.
Жалкая отмазка, однако.
Тут всё-таки взрослые дяди, т.е. без подсказок вкурсе сотен способов сообщить человеку, что он дурак каким-нить "косвенным" образом, навроде "так рассуждают только дураки".
Кароч, детсад, первая четверть.
И при этом твой фирменный стиль.
Который рано или поздно задалбывает, ес-но.
S>Давайте мы в следующий раз всё-таки выпишем вам бан дней на 120, ок?
Давай ты в следующий раз не будешь поднимать градус нервозности по собственной инициативе.
Бери пример с меня — я принципиально отвечаю в подобном ключе только в ответ.
И то, первые пару раз почти всегда игнорю — даю возможность "одуматься".
Неплоха стратегия, рекомендую.
Некому начинать — некому продолжать, очевидно ж.
Re[39]: 2D-Linq и оптимизация цифровых фильтров - 3
Здравствуйте, Sinclair, Вы писали:
V>>Я ХЗ как можно было убить на это столько времени и не выйти на простую абстракцию, примеры которых я показал, назвав их "индексерами"?
S>
S>Эта абстракция мне неинтересна ровно потому, что не позволяет сократить запись прикладных алгоритмов и сделать их более понятными.
Ты спрятал важную подробность алгоритма.
Причём, за нечитаемым кодом.
S>Мне интересна ровно обратная сторона — записать алгоритм так, чтобы скрыть несущественные подробности.
Т.е., ты, таки, прямым текстом расписываешься в собственной необъективности? ))
ОК, так и запишем: разрабатывать эффективные хелперы для обхода двумерных массивов Синклер согласен только для Linq и ни боже упаси для чего-то "другого".
V>>Думаешь, твоё решение читабельней? ))
S>А что тут думать? Я же его привёл.
Нечитабельно.
S>Там одна строчка — меньше уже некуда.
Одна строчка описывает только часть алгоритма, а не целиком его.
Целиком вышло кошмарно.
S>Сколько строчек в вашей реализации самого эффективного c4?
Полностью если? Намного меньше, чем в твоём полном решении.
Мои строчки читабельные и поддерживаемые.
Твои — категорически нет.
V>>"Лапша" тут может быть лишь от попыток свалить все части алгоритма в один цикл.
S>Ну вы же именно это и предложили.
И опять соврал.
Я пока не предлагал ничего, кроме как сделать сравнение честным, т.е. если уж оптимизируется доступ к двумерному массиву, то пусть он оптимизируется для ВСЕХ сравниваемых техник.
S>И даже хвастаетесь — как раз тем, что детали обработки краёв у вас в том же алгоритме.
Но не в том же цикле.
Я ХЗ как можно оставлять процитированное мною, при этом приписывая мне ровно противоположное тому, что я говорил.
Выглядит так, что ты опять и снова запаниковал, бо тут уже запахло сравнением реализации ПОЛНОГО алгоритма, а не упрощенного.
Т.е. когда требуется обработать краевые эффекты согласно некоторому параметру (через заданный цвет бесконечности или через расширение картинки за счёт крайних пикселей).
V>>Разбей алгоритм на несколько частей:
V>>- безопасное, максимально эффективное тело без краевых эффектов;
V>>- проход по краевым эффектам.
S>Совершенно верно.
Ну и где у тебя ограничение прохода лишь по безопасной области массива?
Где и как это выражено?
Ткни пальцем в участок своего кода, если я что-то упустил.
V>>Отрасль с этим Linq подробно разобралась еще лет 10 назад.
S>Вы представляете прекрасный контрпример этому утверждению.
Мы?
Ты пока показал, что и близко Linq еще не нюхал, бо даже не понимаешь, о каких граблях тебе говорят. ))
V>>Ты начни туда прикручивать where, например, сделать c4 только для абсолютно чёрных точек.
S>И в чём проблема? Вы не понимаете, как работает where clause, или что?
Я понимаю как работает перегрузка методов-расширений, поэтому и предлагаю, таки, окунуться чуть поближе, а потом уже делать выводы.
V>>Или сделай из изображения последовательность центральных точек по Вороному.
V>>Помнишь я говорил тебе о конфликте сигнатур?
V>>Похоже ты так и не понял этого замечания. ))
S>Не, не понял. Какая сигнатура и с чем будет конфликтовать?
Ну так ты начни делать и увидишь.
А я рядом пример уже приводил.
Просто пока у тебя в сигнатурах не появилось Select<T, TResult, TCollection>(this TCollection, ...) where TCollection : ISomeInterface<T> — никакой проблемы нет, разумеется.
Обойти это можно только через ConcreteCollection2<TResult> Select<T, TResult>(this ConcreteCollection1<T>, ...), где ConcreteCollection1 — эдакие value-type обертки-маркеры. Но начав покрывать сценарии из обсуждаемой предметной области ты быстро обнаружишь резкий рост комбинаторики на ровном месте. В "стандартном" линке типы стираются через боксинг, но мы-то хотим его избежать, верно?
Кароч, пока сам не попробуешь, так и будешь не понимать о чём речь.
V>>Так вот, "заняв" целиком и полностью сигнатуру Select реализацией с активным возвратом результата, ты обрубил целый пласт алгоритмов.
S>Ну и кто из нас тут демонстрирует непонимание?
Ты, разумеется.
S>Я привёл маленький, короткий proof of concept.
А тебе отвечают люди, которые их делали в количестве за все эти годы.
Просто делятся опытом — с чем пришлось столкнуться и почему так.
И заодно объясняют — почему ты не столкнулся.
Из-за размерности твоего примера.
S>Просто потому, что для форумных обсуждений я не могу потратитьcz на написание полноценного стека с поддержкой всех девяти конструкций query comprehension.
Без боксинга если, то вовсе не 9-ти.
Может я и не прав, что сразу не раскрыл эту часть своих возражений, но до прошлого сообщения я не представлял, насколько ты не в курсе вопроса.
Наивно считал, что простого напоминания о граблях будет достаточно.
S>В реальной промышленной библиотеке конечно же будет возвращаться не T[,], а promise, который будет резолвиться либо явно через .ToArray() либо неявно через вызов [,].
S>Конечно же будет строиться вся цепочка операций.
Ага.
Только у value-типов никаким образом не стираются типы.
S>>>Б) красота линка вовсе не обязательно связана с performance penalty. Внезапно оказывается, что он ещё и быстрее "идиоматического" кода.
V>>Это ложь. Он не быстрее.
S>Бенчмарки утверждают обратное.
Бенчмарки левые, измеряют шумовые эффекты, а не эффективность линка.
Поставь бенчмарки в одинаковые условия, исключи наведённые помехи и измерь снова.
А до тех пор будешь носить клеймо необъективного человека.
V>>Что помешало тебе применить все свои трюки к "идиоматическому" коду, чтобы сравнение вышло спортивным?
S>То, что код с unsafe и манипуляциями указателями не является "идиоматическим".
Сейчас уже можно без unsafe:
Пока оно немного уступает unsafe по эффективности, но обещается, что будет то же самое.
S>Естественно, я эти трюки применил первым же делом — я же сначала написал идеальную версию на С#, и уже потом подсмотрел, какой MSIL надо сгенерировать.
S>Моя задача была дать возможность эти трюки использовать повторно.
S>В вашем подходе код c4 — это двадцать строк; код с8 — ещё 20 строк; код циклического сдвига — ещё 15.
S>А в моём каждый из них — это одна строка.
В показанном тобой коде это не так.
S>Не надо каждый раз считать единички, проверять, куда там сползают указатели, и прочее. Гарантии корректности без потери производительности.
Дык, ты как раз пренебрег гарантиями корректности. ))
Похоже, ты в "гарантии" отнёс только защиту от выхода за границы массива, но пренебрег корректностью алгоритма.
Но в этом случае твоё решение решением НЕ является.
V>>Без конфликтов сигнатур?
S>Ага
Так ты приступи уже, потом приходи, поговорим.
V>>В ответ справедливые технические замечания, на которые у тебя истерика.
S>Технических замечаний нет. Ну не считать же таким, в самом деле, комментарий про использование T[,]. При том, что Array2d всё равно, какой там внутри массив — переписывание на struct FastArray по мотивам вашего индексера заняло 15 минут и не дало никакой (естественно) разницы.
Пипец.
Разница не у тебя должна была появиться, а у "идиоматического" кода.
V>>Подмена задачи случилась у тебя.
V>>А я лишь вытащил на свет божий всё это грязное бельё с подменой задачи. ))
S>Простите, коллега, но вы разговариваете с голосами в своей голове. Я задачу как сформулировал, так и решил.
1. Пока что ты её не решил целиком.
2. В твоей формулировке не утверждалось, что идиоматический код не может пользоваться хелперами.
Хотя в реальных алгоритмах обработки изображений (на тех же плюсах) весь "идиматический" код (т.е. написанный в виде явного итерирования) — он всегда работает поверх неких аналогов показанных мною "индексеров". Потому что по-другому в этой предметной области никак, бо форматов/кодировок даже RAW-изображений слишком много.
Не веришь — спроси у Вольфхаунда, он одно время, вроде бы, занимался такими вещами плотно. ))
V>>Это ведь ты подменил эксперимент по оценке скорости работы линка на эксперимент по ускорению доступа к двумерному массиву.
S>Ну конечно же нет. Задача стояла ровно наоборот — исследовать возможность использования linq для 2d-фильтрации, и возможности не просадить при этом производительность.
В показанном тобой виде возможность отсутствует как класс. Задача не решена. Итоговые пиксели подсчитаны неверно.
Т.е., я пока не увидел в твоём коде ничего помимо трюка с ускорением обхода массива.
Поэтому, я как честный человек, могу обсуждать лишь ту часть задачи, которую тебе удалось решить на данный момент.
Всё остальное от тебя — это лишь обещания "прекрасного будущего", какие мы слышали от тебя же еще с 2003-2004-х годов. ))
Просто мне есть чем возразить — никакого прекрасного будущего там не будет.
Проблематику дизайна линка я подробно расковырял еще хрен его знает когда.
Потому что злоупотребляю value-типами в своих разработках на донете.
Когда/если ты попытаешься окучить всю комбинаторику сценариев, пытаясь при этом избежать боксинга — ты сам всё увидишь.
Пока же тебе удалось (впервые в жизни, судя по уровню радости) написать метод-расширение под линк и тебя банально понесло, ты забыл быть объективным.
V>>Что тебе не понятно во фразе "ограничения генериков не входят в сигнатуры генерик-типов и методов"?
S>Непонятно, почему вы решили, что это помешает в рассматриваемой задаче. Пока что у меня всё получается
Потому что ты подаешь на вход абстрактный ref-тип, которым является массив.
А даже если пробовал Array2d, то максимум в одном сценарии, т.е. еще не нарвался на каскадные Select.
V>>Если придуряешься, то можешь считать себя клоуном.
S> V>Если действительно не понял, то трус и форумный хамло, который вместо простого "я тут недопонял" маскирует своё непонимание через нападки, нимало не смущаясь тем, что увеличивает градус нервозности. Со стороны не пробовал на такие закидоны смотреть? ))
S>Вот, коллега, вот это — переходы на личности. Я свой сарказм проявляю по отношению к вашим аргументам, а не к вашим личным достоинствам или недостаткам.
Жалкая отмазка, однако.
Тут всё-таки взрослые дяди, т.е. без подсказок вкурсе сотен способов сообщить человеку, что он дурак каким-нить "косвенным" образом, навроде "так рассуждают только дураки".
Кароч, детсад, первая четверть.
И при этом твой фирменный стиль.
Который рано или поздно задалбывает, ес-но.
S>Давайте мы в следующий раз всё-таки выпишем вам бан дней на 120, ок?
Давай ты в следующий раз не будешь поднимать градус нервозности по собственной инициативе.
Бери пример с меня — я принципиально отвечаю в подобном ключе только в ответ.
И то, первые пару раз почти всегда игнорю — даю возможность "одуматься".
Неплоха стратегия, рекомендую.
Некому начинать — некому продолжать, очевидно ж.
V>>Я ХЗ как можно было убить на это столько времени и не выйти на простую абстракцию, примеры которых я показал, назвав их "индексерами"?
S>
S>Эта абстракция мне неинтересна ровно потому, что не позволяет сократить запись прикладных алгоритмов и сделать их более понятными.
Ты спрятал важную подробность алгоритма.
Причём, за нечитаемым кодом.
S>Мне интересна ровно обратная сторона — записать алгоритм так, чтобы скрыть несущественные подробности.
Т.е., ты, таки, прямым текстом расписываешься в собственной необъективности? ))
ОК, так и запишем: разрабатывать эффективные хелперы для обхода двумерных массивов Синклер согласен только для Linq и ни боже упаси для чего-то "другого".
V>>Думаешь, твоё решение читабельней? ))
S>А что тут думать? Я же его привёл.
Нечитабельно.
S>Там одна строчка — меньше уже некуда.
Одна строчка описывает только часть алгоритма, а не целиком его.
Целиком вышло кошмарно.
S>Сколько строчек в вашей реализации самого эффективного c4?
Полностью если? Намного меньше, чем в твоём полном решении.
Мои строчки читабельные и поддерживаемые.
Твои — категорически нет.
V>>"Лапша" тут может быть лишь от попыток свалить все части алгоритма в один цикл.
S>Ну вы же именно это и предложили.
И опять соврал.
Я пока не предлагал ничего, кроме как сделать сравнение честным, т.е. если уж оптимизируется доступ к двумерному массиву, то пусть он оптимизируется для ВСЕХ сравниваемых техник.
S>И даже хвастаетесь — как раз тем, что детали обработки краёв у вас в том же алгоритме.
Но не в том же цикле.
Я ХЗ как можно оставлять процитированное мною, при этом приписывая мне ровно противоположное тому, что я говорил.
Выглядит так, что ты опять и снова запаниковал, бо тут уже запахло сравнением реализации ПОЛНОГО алгоритма, а не упрощенного.
Т.е. когда требуется обработать краевые эффекты согласно некоторому параметру (через заданный цвет бесконечности или через расширение картинки за счёт крайних пикселей).
V>>Разбей алгоритм на несколько частей:
V>>- безопасное, максимально эффективное тело без краевых эффектов;
V>>- проход по краевым эффектам.
S>Совершенно верно.
Ну и где у тебя ограничение прохода лишь по безопасной области массива?
Где и как это выражено?
Ткни пальцем в участок своего кода, если я что-то упустил.
V>>Отрасль с этим Linq подробно разобралась еще лет 10 назад.
S>Вы представляете прекрасный контрпример этому утверждению.
Мы?
Ты пока показал, что и близко Linq еще не нюхал, бо даже не понимаешь, о каких граблях тебе говорят. ))
V>>Ты начни туда прикручивать where, например, сделать c4 только для абсолютно чёрных точек.
S>И в чём проблема? Вы не понимаете, как работает where clause, или что?
Я понимаю как работает перегрузка методов-расширений, поэтому и предлагаю, таки, окунуться чуть поближе, а потом уже делать выводы.
V>>Или сделай из изображения последовательность центральных точек по Вороному.
V>>Помнишь я говорил тебе о конфликте сигнатур?
V>>Похоже ты так и не понял этого замечания. ))
S>Не, не понял. Какая сигнатура и с чем будет конфликтовать?
Ну так ты начни делать и увидишь.
А я рядом пример уже приводил.
Просто пока у тебя в сигнатурах не появилось Select<T, TResult, TCollection>(this TCollection, ...) where TCollection : ISomeInterface<T> — никакой проблемы нет, разумеется.
Обойти это можно только через ConcreteCollection2<TResult> Select<T, TResult>(this ConcreteCollection1<T>, ...), где ConcreteCollection1 — эдакие value-type обертки-маркеры. Но начав покрывать сценарии из обсуждаемой предметной области ты быстро обнаружишь резкий рост комбинаторики на ровном месте. В "стандартном" линке типы стираются через боксинг, но мы-то хотим его избежать, верно?
Кароч, пока сам не попробуешь, так и будешь не понимать о чём речь.
V>>Так вот, "заняв" целиком и полностью сигнатуру Select реализацией с активным возвратом результата, ты обрубил целый пласт алгоритмов.
S>Ну и кто из нас тут демонстрирует непонимание?
Ты, разумеется.
S>Я привёл маленький, короткий proof of concept.
А тебе отвечают люди, которые их делали в количестве за все эти годы.
Просто делятся опытом — с чем пришлось столкнуться и почему так.
И заодно объясняют — почему ты не столкнулся.
Из-за размерности твоего примера.
S>Просто потому, что для форумных обсуждений я не могу потратитьcz на написание полноценного стека с поддержкой всех девяти конструкций query comprehension.
Без боксинга если, то вовсе не 9-ти.
Может я и не прав, что сразу не раскрыл эту часть своих возражений, но до прошлого сообщения я не представлял, насколько ты не в курсе вопроса.
Наивно считал, что простого напоминания о граблях будет достаточно.
S>В реальной промышленной библиотеке конечно же будет возвращаться не T[,], а promise, который будет резолвиться либо явно через .ToArray() либо неявно через вызов [,].
S>Конечно же будет строиться вся цепочка операций.
Ага.
Только у value-типов никаким образом не стираются типы.
S>>>Б) красота линка вовсе не обязательно связана с performance penalty. Внезапно оказывается, что он ещё и быстрее "идиоматического" кода.
V>>Это ложь. Он не быстрее.
S>Бенчмарки утверждают обратное.
Бенчмарки левые, измеряют шумовые эффекты, а не эффективность линка.
Поставь бенчмарки в одинаковые условия, исключи наведённые помехи и измерь снова.
А до тех пор будешь носить клеймо необъективного человека.
V>>Что помешало тебе применить все свои трюки к "идиоматическому" коду, чтобы сравнение вышло спортивным?
S>То, что код с unsafe и манипуляциями указателями не является "идиоматическим".
Сейчас уже можно без unsafe:
[StructLayout(LayoutKind.Sequential, Pack =1)]
public struct Rgb24 {
public byte R;
public byte G;
public byte B;
public Rgb24(byte r, byte g, byte b) {
R = r;
G = g;
B = b;
}
}
class Program {
static void Main(string[] args) {
Rgb24[,] image = {
{ new Rgb24(1, 2, 3), new Rgb24(4, 5, 6) },
{ new Rgb24(7, 8, 9), new Rgb24(10, 11, 12) }
};
var bytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref image[0, 0], image.Length));
foreach(byte b in bytes)
Console.WriteLine(b);
}
}
Пока оно немного уступает unsafe по эффективности, но обещается, что будет то же самое.
S>Естественно, я эти трюки применил первым же делом — я же сначала написал идеальную версию на С#, и уже потом подсмотрел, какой MSIL надо сгенерировать.
S>Моя задача была дать возможность эти трюки использовать повторно.
S>В вашем подходе код c4 — это двадцать строк; код с8 — ещё 20 строк; код циклического сдвига — ещё 15.
S>А в моём каждый из них — это одна строка.
В показанном тобой коде это не так.
S>Не надо каждый раз считать единички, проверять, куда там сползают указатели, и прочее. Гарантии корректности без потери производительности.
Дык, ты как раз пренебрег гарантиями корректности. ))
Похоже, ты в "гарантии" отнёс только защиту от выхода за границы массива, но пренебрег корректностью алгоритма.
Но в этом случае твоё решение решением НЕ является.
V>>Без конфликтов сигнатур?
S>Ага
Так ты приступи уже, потом приходи, поговорим.
V>>В ответ справедливые технические замечания, на которые у тебя истерика.
S>Технических замечаний нет. Ну не считать же таким, в самом деле, комментарий про использование T[,]. При том, что Array2d всё равно, какой там внутри массив — переписывание на struct FastArray по мотивам вашего индексера заняло 15 минут и не дало никакой (естественно) разницы.
Пипец.
Разница не у тебя должна была появиться, а у "идиоматического" кода.
V>>Подмена задачи случилась у тебя.
V>>А я лишь вытащил на свет божий всё это грязное бельё с подменой задачи. ))
S>Простите, коллега, но вы разговариваете с голосами в своей голове. Я задачу как сформулировал, так и решил.
1. Пока что ты её не решил целиком.
2. В твоей формулировке не утверждалось, что идиоматический код не может пользоваться хелперами.
Хотя в реальных алгоритмах обработки изображений (на тех же плюсах) весь "идиматический" код (т.е. написанный в виде явного итерирования) — он всегда работает поверх неких аналогов показанных мною "индексеров". Потому что по-другому в этой предметной области никак, бо форматов/кодировок даже RAW-изображений слишком много.
Не веришь — спроси у Вольфхаунда, он одно время, вроде бы, занимался такими вещами плотно. ))
V>>Это ведь ты подменил эксперимент по оценке скорости работы линка на эксперимент по ускорению доступа к двумерному массиву.
S>Ну конечно же нет. Задача стояла ровно наоборот — исследовать возможность использования linq для 2d-фильтрации, и возможности не просадить при этом производительность.
В показанном тобой виде возможность отсутствует как класс. Задача не решена. Итоговые пиксели подсчитаны неверно.
Т.е., я пока не увидел в твоём коде ничего помимо трюка с ускорением обхода массива.
Поэтому, я как честный человек, могу обсуждать лишь ту часть задачи, которую тебе удалось решить на данный момент.
Всё остальное от тебя — это лишь обещания "прекрасного будущего", какие мы слышали от тебя же еще с 2003-2004-х годов. ))
Просто мне есть чем возразить — никакого прекрасного будущего там не будет.
Проблематику дизайна линка я подробно расковырял еще хрен его знает когда.
Потому что злоупотребляю value-типами в своих разработках на донете.
Когда/если ты попытаешься окучить всю комбинаторику сценариев, пытаясь при этом избежать боксинга — ты сам всё увидишь.
Пока же тебе удалось (впервые в жизни, судя по уровню радости) написать метод-расширение под линк и тебя банально понесло, ты забыл быть объективным.
V>>Что тебе не понятно во фразе "ограничения генериков не входят в сигнатуры генерик-типов и методов"?
S>Непонятно, почему вы решили, что это помешает в рассматриваемой задаче. Пока что у меня всё получается
Потому что ты подаешь на вход абстрактный ref-тип, которым является массив.
А даже если пробовал Array2d, то максимум в одном сценарии, т.е. еще не нарвался на каскадные Select.
V>>Если придуряешься, то можешь считать себя клоуном.
S> V>Если действительно не понял, то трус и форумный хамло, который вместо простого "я тут недопонял" маскирует своё непонимание через нападки, нимало не смущаясь тем, что увеличивает градус нервозности. Со стороны не пробовал на такие закидоны смотреть? ))
S>Вот, коллега, вот это — переходы на личности. Я свой сарказм проявляю по отношению к вашим аргументам, а не к вашим личным достоинствам или недостаткам.
Жалкая отмазка, однако.
Тут всё-таки взрослые дяди, т.е. без подсказок вкурсе сотен способов сообщить человеку, что он дурак каким-нить "косвенным" образом, навроде "так рассуждают только дураки".
Кароч, детсад, первая четверть.
И при этом твой фирменный стиль.
Который рано или поздно задалбывает, ес-но.
S>Давайте мы в следующий раз всё-таки выпишем вам бан дней на 120, ок?
Давай ты в следующий раз не будешь поднимать градус нервозности по собственной инициативе.
Бери пример с меня — я принципиально отвечаю в подобном ключе только в ответ.
И то, первые пару раз почти всегда игнорю — даю возможность "одуматься".
Неплоха стратегия, рекомендую.
Некому начинать — некому продолжать, очевидно ж.