Здравствуйте, Ikemefula, Вы писали:
I>Когда ты начинаешь сливаться, то всегда притягиваешь этот мем с имаго. Так, наблюдения.
Или ты начинаешь использовать этот прием когда сливаешься.
I>"кейс был подробно расписан". Давай смотреть вместе. Вот собтсвенно это описание "Боксирование же нескольких десятков строк в".
Кейс вот:
надо было бы тоже боксировать для GUI, приводя к Object.
Речь о дотнетном биндинге. Это вполне конкретный механизм, действительно требующий object. Если ты про это не знаешь — спроси.
I>А я тебе говорю, что может быть и на порядки больше данных
А я сказал, что не нужно биндить на контролы большие объемы данных, это не имеет смысла. Гриды сейчас делают виртуальные, и боксинг там вылазит только для того что отображается. Если же ты додумался в невиртуальный грид загнать большие объемы, то боксинг у тебя будет примерно на десятом месте после других проблем.
НС>>А не надо затягивать в гуй большой объем данных, человек все равно много данных за раз не сможет воспринять. I>Похоже, ты про САПР только слышал.
Похоже ты опять не понимаешь про что речь.
I>>>, это дает конские издержки. Вместо мелкой операции в пересчете на объект получаем конские издержки на боксинг-анбоксинг НС>>Издержки на боксинг, если мы говорим про гуй, совсем не конские. Конские они когда тебе гигабайты перемолотить надо. I>Цитирую себя: "Выборка >1gb." Ты реально что ли не читая строчишь?
Нет, это ты реально тупишь и не понимаешь о чем речь.
>>А в гуе на фоне отработки лейаута и рендеринга шрифтов боксинг не разглядеть и в микроскоп. I>Профайлер с тобой не согласен. Ты извини, но САПР я занимался 12 лет на дотнете и С++.
Что рисовал? У тебя при отрисовке в САПР модели в 1Гб был боксинг? Нафига?
НС>>Это не имеет никакого отношения к биндингу рекордсетов на контролы. Соответственно и проблемы боксинга при этом никакой нет. I>Ты всё про тупенькие контролы
Я с самого начала про них писал, как и vdimas. А ты упорно пытаешься что то другое пообсуждать.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[62]: MS забило на дотнет. Питону - да, сишарпу - нет?
Без виртуализации обычный список может использовать цикл C# foreach для отрисовки каждого элемента в списке. В следующем примере:
allFlights представляет собой коллекцию рейсов самолетов.
Компонент FlightSummary отображает сведения о каждом рейсе.
Атрибут директивы @key сохраняет связь каждого компонента FlightSummary с его отображаемым рейсом элемента FlightId рейса.
Если коллекция содержит тысячи рейсов, отрисовка рейсов занимает много времени и пользователи сталкиваются с заметной задержкой отображения пользовательского интерфейса. Большинство рейсов не отрисовываются, потому что они выходят за пределы высоты элемента <div>.
Вместо отрисовки сразу всего списка рейсов замените цикл foreach в предыдущем примере на компонент Virtualize:
Укажите allFlights как источник фиксированного элемента для Virtualize<TItem>.Items. Компонент Virtualize выполняет отрисовку только видимых в данный момент рейсов.
Укажите контекст для каждого рейса с помощью параметра Context. В следующем примере элемент flight используется в качестве контекста, который обеспечивает доступ к каждому участнику рейса.
Если контекст не указан с помощью параметра Context, используйте значение context в шаблоне содержимого элемента, чтобы получить доступ к членам каждого рейса:
вычисляет количество подлежащих отрисовке элементов на основе высоты контейнера и размера отображаемых элементов;
пересчитывает и повторно отрисовывает элементы при прокрутке пользователем;
извлекает из внешнего API только тот срез записей, который соответствует текущей видимой области, не скачивая все данные из коллекции.
Содержимое элемента для компонента Virtualize может включать в себя следующее:
обычный код HTML и код Razor, как показано в предыдущем примере;
один или несколько компонентов Razor;
сочетание компонентов HTML/Razor и Razor.
и солнце б утром не вставало, когда бы не было меня
Re[63]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Ночной Смотрящий, Вы писали:
I>>Когда ты начинаешь сливаться, то всегда притягиваешь этот мем с имаго. Так, наблюдения. НС>Или ты начинаешь использовать этот прием когда сливаешься.
I>>"кейс был подробно расписан". Давай смотреть вместе. Вот собтсвенно это описание "Боксирование же нескольких десятков строк в".
НС>Кейс вот: НС>
НС>надо было бы тоже боксировать для GUI, приводя к Object.
Правильно понимаю, в этой строчке правила логики лично тебе подсказывают, что речь про несколько десятков строк?
Откуда ты взял эти "несколько десятков строк" ?
НС>>>Издержки на боксинг, если мы говорим про гуй, совсем не конские. Конские они когда тебе гигабайты перемолотить надо. I>>Цитирую себя: "Выборка >1gb." Ты реально что ли не читая строчишь?
НС>Нет, это ты реально тупишь и не понимаешь о чем речь.
Ты адекватен? Смотрим вместе хронологию сообщений:
Мое — ...Выборка >1gb.
Твое — ...Конские они когда тебе гигабайты перемолотить надо.
Очевидно, нечитатель. То есть, принципиальных возражений у тебя нет.
I>>Профайлер с тобой не согласен. Ты извини, но САПР я занимался 12 лет на дотнете и С++. НС>Что рисовал?
Сеть, худший случай — рисуем все, когда юзер фильтрам-зумами-слоями включил всё. Апликачка должны быть живой и не мерзнуть.
Скажем, надписи юзер может и выключить, это раз, а они необязательно поменяются, т.к. этот слой достается забесплатно, это два.
>У тебя при отрисовке в САПР модели в 1Гб был боксинг? Нафига?
Конечно же нет. На него издержки конские, потому я его истреблял всеми доступными мне методами.
I>>Ты всё про тупенькие контролы
НС>Я с самого начала про них писал, как и vdimas. А ты упорно пытаешься что то другое пообсуждать
Разумеется, я пишу о том, что необязательно тупенькие контролы использовать.
Re[63]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Serginio1, Вы писали:
I>>То есть, ты просто от балды по ходу беседы вбросил, что де будет именно несколько десятков строк. I>>А я тебе говорю, что может быть и на порядки больше данных, и тогда боксинг станет существенным препятствием. S>Ну вообще то даже в блазоре сейчас используется виртуализация.
Спасибо, Капитан! Не знал, что ты это предложишь сегодня, запилил это лет двенадцать назад.
Тем не менее юзер в САПР может её отключить и приложение все равно должно остаться рабочим.
Здравствуйте, Ikemefula, Вы писали: I>Спасибо, Капитан! Не знал, что ты это предложишь сегодня, запилил это лет двенадцать назад. I>Тем не менее юзер в САПР может её отключить и приложение все равно должно остаться рабочим.
Виртуализацию в блазор ввели недавно. А насчет отключить. Юзер может тащить многогигабайтные данные и работать ничего не будет. Памяти не хватит!
А гуй реально работает только с отображаемыми данными. И по сравнению с графикой боксинг это отнюдь не лимитирующая стадия процесса.
и солнце б утром не вставало, когда бы не было меня
Re[57]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Serginio1, Вы писали:
V>>Движется к более безопасному и более удобному такому общению. V>>Де-факто ни одной новой задачи нововведения языка в этой области решать не позволяют, они позволяют более удобно решать старые задачи. S>А какие новые задачи?
Например, позволить unamanaged-указателям быть аргументами генериков.
Сейчас для того же самого приходится вводить некий прокси-тип:
readonly struct Pointer<T> where T : unmanaged {
public T * Value;
public Pointer(T * ptr) => Value = ptr;
}
[StructLayout(LayoutKind.Explicit)]
struct SomeUnion<T1, T2, T3>
where T1: unmanaged
where T2: unmanaged
where T3: unmanaged
{
Type _desc;
[FieldOffset(0)] T1 u1;
[FieldOffset(0)] T2 u2;
[FieldOffset(0)] T3 u3;
internal static ref GetRef<T> (ref @this) {
if(typeof(T) != _desc) throw new InvalidOperationException("Blah-blah-blah");
return Unsafe.As<T1, T>(ref @this.u1);
}
public void Extract<T>(ref T extractor) where T : IUnionExtractor<T1, T2, T3> {
}
...
}
public static class SomeUnionExt {
public T Get<T, T1, T2, T3> (ref this SomeUnion<T1, T2, T3> @this) where ... => SomeUnion<T1, T2, T3>.GetRef<T>(@this);
public ref T GetRef<T, T1, T2, T3> (ref this SomeUnion<T1, T2, T3> @this) where ... => ref SomeUnion<T1, T2, T3>.GetRef<T>(@this);
...
SomeUnion<Pointer<byte>, int, IntPtr> u = ...;
Еще момент — статическая линковка нейтивного кода.
Каким-то образом (по крайней мере в .Net Framework так было) они собирают свои либы так, что некоторая функциональность только объявляется на стороне дотнета, но реализуется унутре.
Здравствуйте, Sinclair, Вы писали:
S>> Пусть лучше будет копирование, но в одном процессе как в Сингулярити https://www.rsdn.org/article/singularity/singularity.xml S>>Что бы те же EF, Linq2DB работали на SQL сервере! На Java что то есть для оракула, но как то не особо об этом говорят. S>В SQL Server дотнет можно исполнять уже больше 15 лет, примерно так же, как и Java в Oracle.
В джаве можно получать джавовские юзер-типы, а в SQL-сервер датасеты с object-тами внутри.
Это не то...
Re[63]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Ikemefula, Вы писали:
V>>Статистика чего именно, если речь шла о доступности/развитости ср-в рефакторинга? I>Доступность/развитость это все статистика
Кошмар. ))
Стати́стика — отрасль знаний, наука, в которой излагаются общие вопросы сбора, измерения, мониторинга, анализа массовых статистических (количественных или качественных) данных и их сравнение; изучение количественной стороны массовых общественных явлений в числовой форме.
Для сравнения программных продуктов достаточно сравнения их функциональности/характеристик.
Это может выполнить любой более-менее опытный специалист.
I>>>У тебя же вместо статистики "я дал ему третье место" V>>И вполне заслуженно. I> Ты всерьёз не понял, что речь была не про твой личный топ?
Да понял я всё прекрасно.
Возгорание в стиле "нам это слышать неприятно".
До сих пор полыхает, судя по использованным смайликам.
Re[58]: MS забило на дотнет. Питону - да, сишарпу - нет?
Кстати нет наследования структур. Сейчас с source generator упрощается расширение классов.
Хотя всегда можно сделать структуру с полем наследуемой структуры и нагенерить свойства и методы над наследуемой структурой с помощью того же source generator
и солнце б утром не вставало, когда бы не было меня
Re[48]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, vdimas, Вы писали:
V>А как, по-твоему, возращается по-значению структура, размер которой больше ширины регистра?
Как и всё — кладётся в стек. V>Для инфы, в этом сценарии существует т.н. return value optimization (гугл).
V>>>Получить ref или readonly ref-ссылку на поле структуры через метод самой структуры нельзя, можно только через метод-расширение, где саму структуру передавать через ref this.
V>Офигеть. )) V>Ты только что нашёл баг компилятора:
Нда, прикольно. V>Надо проверить в 10-м C# и зарепортить, если еще не починили.
V>В любых flexible-структурах фактическая длина известна после получения данных из некоторого АПИ. V>Некий публичный метод или св-во могли бы возвращать Span.
Да, можно так. А можно и скрыть факт наличия спана (если мы не хотим, чтобы его ещё куда-то кастили), и просто выставлять наружу индексер.
V>1. Дотнет не гарантирует фактический порядок расположение полей, необходимо задать StructLayout хотя бы Sequential
Ну да, естественно.
V>Мне показалось, что ты хотел сделать Span как часть описания структуры.
Нет, тогда конечно же сломается Layout.
V> public Span<int> AsSpan() => MemoryMarshal.CreateSpan(ref _data0[0], Length);
Я так и использую — в тех местах, где мне нужен Span.
Вот, текущее состояние экспериментов https://github.com/evilguest/atropos/blob/main/Atropos/BranchNode.cs#L37
К сожалению, ожидаемый инлайнинг this[] в https://github.com/evilguest/atropos/blob/main/Atropos/BranchNode.cs#L28 не происходит, несмотря на то, что T — это struct тип, точно известный в момент JIT
Поэтому с перформансом у текущей версии всё гораздо хуже, чем у предыдущей.
V>Тогда for-циклы по полному Span-у соптимизируют одну проверку за выход за диапазон, как это делается для обычных массивов.
Именно.
V>Неблокирующий вызов не означает не использование примитивов синхронзации, а там сказано: V>
V>* Not manipulate locks or other concurrency primitives
Опять же в доке сказано, что из разных потоков работать с зокетами нельзя. Так что явно там нет никаких примитивов синхронизации.
V>На моей машине в 17 раз. V>И у тебя там замеры вообще странные были, если по твоим замерам простой вызов выходил 7 ns.
Возможно, я там поделил неверно. В текущей версии количество внутренних итераций поправлено, так что можно просто заменять миллисекунды на наносекунды.
V>Т.е., при каждом обновлении.
Чаще
V>Выглядит так, что у тебя своеобразные представления как о возможностях AOT, так и о возможностях hot-spot оптимизаций.
У меня своеобразные представления о том, как что должно работать.
V>>>Скорее, оптимизатор заинлайнит что-то в кишках XML-сериализатора, но верхние уровни пойдут как есть. S>>Ну, в нашем случае мы написали высокопроизводительный XML-сериализатор на $"<flightData><flightNo>{Escape(d.GetString(0))}</flightNo><departureDate>{d.GetDate(1).ToString(r)}</departureDate></flightData>"
V>Вручную писаный сериализатор будет оптимизирован и в АОТ,
Каким образом? На основании чего АОТ будет выполнять спекулятивный инлайнинг?
V>Верно, АОТ потенциально способно убирать лишнюю косвенность. V>Например, "выпрямлять" в памяти банальный List<T>.
Что значит "выпрямлять"? Он же уже и так прямой.
V>Статистика в основном нужна для определения мест, где требуется оптимизация.
Мы ходим по кругу. Ну вот мы увидели, что у нас в горячем цикле вызывается _serializer.Serialize(dataReader, stringBuilder).
Дальше что? Это косвенный вызов по интерфейсу.
V>В рекордсете из 1001 элемента первые 1000 будут прочитаны без оптимизации. V>Затем будет выполнена дорогостоящая оптимизация и последний элемент прочитают оптимальным образом.
Ага. Зато последующие обращения к этому же датасету будут уже оптимальны. А АОТ так и оставит косвенный вызов через VMT.
V>У тебя в "одном и том же месте" каждый раз будут разные экземпляры DataReader и потенциально хотя бы немного отличающиеся схемы, хотя бы в плане nullable-полей, особенно если со стороны базы позвали какой-нить union. И даже если схемы будут те же — это будут другие экземпляры схем, вот в чём прикол.
При чём тут экземпляры? Речь о коде методов, т.е. о содержимом VMT. И о ветвлениях.
V>В случае DataReader в нынешнем виде не прокатит — слишком большая иерархия объектов, всю её проверять на соответствие текущему хот-спот-коду будет накладней получаемых от хот-спот плюшек.
И удивительным образом, Java ухитряется сворачивать вполне себе прикладной код в приемлемый x86/x64.
V>Тогда динамически (по индексу) будет обращение только к строке такой таблицы, а столбец известен статически. V>Тогда проверка соответствия лейаута объекта будет сводиться к проверке только ссылок на метаинформацию столбцов рекодрсета, где эти столбцы ссылаются на одни и те же статические-заготовленные конвертеры.
И даже такую конструкцию способен улучшить хотспот.
V>Т.е. сравни — проверить только равенство ссылок в объекте верхнего уровня или рекурсивно пройтись по кучерявым объектам, проверяя равенство всех полей всех дочерних элементов. V>Счётчик сложности в последнем случае скажет "извините, в другой раз".
Вот это уже интересный вопрос. Всё зависит от того, сколько у нас реальных типов используется внутри тела цикла. Там не нужно проверять "равенство всех-всех полей".
V>"Норма" там в простейших случаях. V>Я разбирал примеры работы джавовского хот-спота — покрывает только тривиальнейшие случаи и уже даже про них трубят как о победе.
Я настолько глубоко именно в джавовском хотспоте не разбирался — в основном читал статьи и общался с людьми, которые пилили высокопроизводительные приложения. Причём ещё в начале 2000х, задолго до GraalVM.
V>Распространённая ошибка. V>Я показал устройство таблицы конвертеров в сообщении, на которое уже давал ссылку. V>Читабельность и поддерживаемость (то бишь расширяемость) прекрасная. V>А в варианте с новыми указателями на ф-ии — еще и максимально-эффективная, т.е. даже, грубо, на асме или IL быстрее не сделаешь.
Навскидку не видно, благодаря чему это будет быстрее вызова через интерфейс — ведь в реальности у нас будет не просто вызов по указателю. Сначала надо будет достать по указателю таблицу функций (рукопашный аналог VMT), и уже потом из неё выбирать слот. Впрочем, нужно профилировать.
V>ОК, про гипотетический хотспот пока спорить не буду, по крайней мере пока его нет в природе для .Net.
Да, пока что наша проблема не в том, что хотспот недостаточно хорош, а в том, что его вовсе нет. Умение выбрать места для оптимизации у JIT уже есть, но этого недостаточно — с таким уровнем умения обыграть АОТ невозможно по определению.
V>Нигде.
Вот то-то и оно. Так что вы итоге мы обсуждаем гипотетический АОТ vs гипотетичексий хотспот.
В моей идеальной картине мира они сосуществуют: то есть АОТ работает заранее, возможно, с применением PGO. Как опциональный компонент, призванный улучшить время холодного старта.
А затем в дело вступает хотспот, который докомпилирует динамический код (если такой появится), и использует рантайм статистику для дальнейших оптимизаций уже и так неплохого кода.
V>Даже существующий полноценный доступен только для iOS на основе mono (ХЗ какого он там качества). V>А виндовые UWP-приложения на .Net Core UWP компиляются серверами магазина Windows под сетку устройств, тот код публично недоступен.
Так нам же не исходники АОТ нужны. Была бы возможность плагинов — был бы публичный API.
V>Я помню обратное — ты так и не прошёл понимание про повторно-используемые "кубики" при построении плана запроса.
Я привёл пример "плана запроса" и просил показать, какие его запчасти можно повторно использовать для альтернативных планов того же запроса, или каких-то других запросов.
V>Псевдокод давался.
Да, мной.
V>Это для динамических вещей. V>Для статических еще в момент компиляции известны наличествующие индексы.
Для любых. Дело не в динамике, а в количестве сочетаний. V>Поэтому, комбинаторика будет только по различиям в статистике, где для многих типов индексов, которые я обозвал enum (разновидность справочных данных эдакого системного плана, т.е. которые жестко привязаны к версии приложения) — статистика известна на момент компиляции. То бишь, кол-во уникальных значений в индексе, характер этих значений (подряд или разрежёнными "островками" и т.д.).
В реальной системе таких "индексов" пренебрежимо мало.
V>Т.е., вместо V>
V>class SomeClass { int a, b, c; };
V>SomeClass c1 = new SomeClass[42];
V>
V>У них идёт: V>
V>int[] aFields = new int[42];
V>int[] bFields = new int[42];
V>int[] cFields = new int[42];
V>
Ну, так это известный трюк, связанный не столько с хотспотом, сколько с отсутствием value-типов. А иногда — и с тем, что мы хотим получить автовекторизацию, которая не работает в случае int a; int b; int c.
V>А в самых критических случаях и вовсе: V>
V>class SomeClassHelper {
V> const int FIELD_COUNT = 3;
V> const int FIELD_A_OFFSET = 0;
V> const int FIELD_B_OFFSET = 1;
V> const int FIELD_C_OFFSET = 2;
V> public void write(int[] array, int index, int a, int b, int c) {
V> index = index * FIELD_COUNT;
V> array[index + FIELD_A_OFFSET] = a;
V> ...
V>}
Это тоже известный трюк
V>int[] data = ...
V>SomeClassHelper.Write(data, index, a, b, c);
V>
V>Смысл примерно должен быть понятен. V>А если поля разных типов (по ширине разных), то всё еще забавнее происходит над массивом байт.
V>Вытягивают её ручками, помогая хот-споту.
Ну, по честному это применяется только в том случае, если перформанс прямо очень важен, а себестоимость разработки — нет. А обычные гражданские приложения, написанные идиоматическим образом, работают приемлемо быстро.
V>Сам понимаешь, поддерживаемость ТАКОГО кода ни идёт ни в какое сравнение с предложенной мною микро-оптимизацией на основе таблицы диспетчеризации конвертеров.
Да, с этим я не спорю. Именно поэтому мне CLR нравится больше, чем JVM.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[65]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Serginio1, Вы писали:
I>>Спасибо, Капитан! Не знал, что ты это предложишь сегодня, запилил это лет двенадцать назад. I>>Тем не менее юзер в САПР может её отключить и приложение все равно должно остаться рабочим.
S>Виртуализацию в блазор ввели недавно. А насчет отключить. Юзер может тащить многогигабайтные данные и работать ничего не будет. Памяти не хватит!
Все что надо — работает. Никто не говорит про отрисовку каждого бита, не надо доводить всё до абсурда.
S>А гуй реально работает только с отображаемыми данными. И по сравнению с графикой боксинг это отнюдь не лимитирующая стадия процесса.
Разумеется не лимитирующая — потому что он старательно вырезан отовсюду, куда можно дотянуться.
Re[59]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Serginio1, Вы писали:
S>Кстати нет наследования структур. Сейчас с source generator упрощается расширение классов.
Это палка о двух концах.
Отсутствие наследования означает, что код можно делать очень эффективным — например, везде, где мы используем структуру хоть бы и по ссылке, нам известен точный тип.
Помимо раскладки полей (которую при наследовании можно сделать совместимой с предком), это позволяет не бегать по VMT при вызове методов.
Частным случаем является многократно упомянутый в этой же дискуссии трюк с параметризацией генерика структурным типом, ограниченным интерфейсом.
Таким образом, имеем полиморфизм без штрафов к производительности. S>Хотя всегда можно сделать структуру с полем наследуемой структуры и нагенерить свойства и методы над наследуемой структурой с помощью того же source generator
Так сделать можно, но нельзя будет передать ref Descendant в параметр, где ожидается ref Parent.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[57]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, vdimas, Вы писали:
V>В джаве можно получать джавовские юзер-типы, а в SQL-сервер датасеты с object-тами внутри.
Хотелось бы поподробнее.
Как раз в SQL-сервер можно внедрять дотнетные юзер-типы (и именно так, в частности, устроен новый тип HierarchyId), а в оракле — х.з.
С другой стороны, при написании Stored Procedures и в Java/Oracle, и в CLR/MSSQL, мы всего лишь тащим внутрь датасеты через "локальное соединение", со всеми вытекающими последствиями (типа той же конверсии данных между неуправляемым и управляемым миром).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[60]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>>Кстати нет наследования структур. Сейчас с source generator упрощается расширение классов. S>Это палка о двух концах. S>Отсутствие наследования означает, что код можно делать очень эффективным — например, везде, где мы используем структуру хоть бы и по ссылке, нам известен точный тип.
Хорошо сделать не наследование а копирование. полей и методов.
и солнце б утром не вставало, когда бы не было меня
Re[64]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Ikemefula, Вы писали:
I>Откуда ты взял эти "несколько десятков строк" ?
Ты опять не читаешь собеседника. Я писал откуда.
I>>>Профайлер с тобой не согласен. Ты извини, но САПР я занимался 12 лет на дотнете и С++. НС>>Что рисовал? I>Сеть, худший случай — рисуем все, когда юзер фильтрам-зумами-слоями включил всё.
И сеть биндится через штатный биндинг, да?
>>У тебя при отрисовке в САПР модели в 1Гб был боксинг? Нафига? I>Конечно же нет. На него издержки конские, потому я его истреблял всеми доступными мне методами.
Т.е. изначально он там был?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[61]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Serginio1, Вы писали: S>Хорошо сделать не наследование а копирование. полей и методов.
С одной стороны, звучит как задача для source generators.
То есть помечаем интересные нам структуры атрибутом:
public struct Parent
{
private int _a;
public int GetA() => _a;
}
[Inherits(typeof(Parent))]
public partial struct Child
{
private int _b;
public int GetB() = >_b;
}
И source generator втаскивает в нашу структуру всё подряд из предка, добавляя
public partial struct Child
{
private int _a;
public int GetA() => _a;
}
C другой стороны — начинаются всякие вопросы типа "что делать с конструкторами", т.к. вот такой код будет падать с CS0171: Field 'C.Child._a' must be fully assigned before control is returned to the caller:
[Inherits(typeof(Parent))]
public partial struct Child
{
private int _b;
public int GetB() = >_b;
public Child() => _b = 0;
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[60]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:
S>Отсутствие наследования означает, что код можно делать очень эффективным — например, везде, где мы используем структуру хоть бы и по ссылке, нам известен точный тип.
Запретить виртуальные методы для структур?
А при боксировании поданной по ссылке структуры боксировать только поданную "часть" структуры.
S>Частным случаем является многократно упомянутый в этой же дискуссии трюк с параметризацией генерика структурным типом, ограниченным интерфейсом.
Там все-равно уникальный код под структуру генерится джитом.
Кстате, и тут АОТ может помочь, бо если две структуры имеют одинаковый лейаут и функциональность, то и сгенерённый код под них мог бы бы одинаковый.
Например, как все инстансы Pointer<T>.
S>Таким образом, имеем полиморфизм без штрафов к производительности.
До боксирования там, считай, compile-time полиморфизм.
S>>Хотя всегда можно сделать структуру с полем наследуемой структуры и нагенерить свойства и методы над наследуемой структурой с помощью того же source generator S>Так сделать можно, но нельзя будет передать ref Descendant в параметр, где ожидается ref Parent.
Именно.
Хотя, при передаче по-значению можно выкрутиться через implicit-оператор приведения типа.
Re[62]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:
S>>Хорошо сделать не наследование а копирование. полей и методов. S>С одной стороны, звучит как задача для source generators.
Всё что может генератор кода, потенциально может и компилятор. ))
Re[62]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, Sinclair, Вы писали:
S>C другой стороны — начинаются всякие вопросы типа "что делать с конструкторами", т.к. вот такой код будет падать с CS0171: Field 'C.Child._a' must be fully assigned before control is returned to the caller:
Ну мы же можем скопировать тело конструктора предка в конструктор потомка.
и солнце б утром не вставало, когда бы не было меня
Re[61]: MS забило на дотнет. Питону - да, сишарпу - нет?
Здравствуйте, vdimas, Вы писали:
V>Там все-равно уникальный код под структуру генерится джитом.
Генерится-то он джитом, но виртуальный вызов заменяется прямым ровно потому, что нельзя передать в метод Foo(ref T val) ссылку на потомка T.
А запрет на виртуальные методы в данном контексте плавно превращается в запрет реализовывать интерфейсы, чтобы избежать странных эффектов.
Ну, либо правила определения того, что можно, а что нельзя, становятся чрезмерно сложными.
V>Кстате, и тут АОТ может помочь, бо если две структуры имеют одинаковый лейаут и функциональность, то и сгенерённый код под них мог бы бы одинаковый.
Так-то и джит мог бы "увидеть", что две структуры имеют одинаковый лэйаут, то можно сравнить MSIL методов и для совпадающих методов генерировать одну копию кода. V>Например, как все инстансы Pointer<T>.
Речь про велосипед типа https://www.codeproject.com/Articles/1254502/Creating-a-pointer-type-in-Csharp?
Или есть какой-то кошерный Pointer<T>, на который можно посмотреть?
V>Именно. V>Хотя, при передаче по-значению можно выкрутиться через implicit-оператор приведения типа.
Ну, это будет одновременно криво и неэффективно
Уйдемте отсюда, Румата! У вас слишком богатые погреба.