Обновить
-1

Пользователь

Отправить сообщение

Накладными расходами, очевидно.

В качестве обмена опытом: в сценариях, где важна [даже относительно] высокая производительность SortedDictionary не подходит: производительность добавления ожидаемая, но на каждое добавление происходить выделение памяти, скорость поиска ожидаемо невысокая, перечисление медленное, при перечислении выделяет память.

SortedList, к слову, тоже так себе. Не помню уже кто был быстрее, кто медленнее, помоему SortedList побыстрее, но точно размещает меньше индивидуальных инстанцев в куче.

При необходимости рекомендую проанализировать сценарий и написать свой специализированный компонент.

С другой стороны, в клиентском приложении на ЮИ не на горячем пути вполне применим.

Поддерживаю вопрос товарища @dopusteam

У меня есть несколько догадок касательно того, что имелось ввиду, но ни в одной не уверен.

Локальная переменная теперь оказывается не работает как локальная, но работает как метод.

А когда локальная переменная передаётся как ref - она перестаёт работать как локальная?

Для рантайма она больше не локальная переменная, но это скрыто и незаметно (пока не упираемся в особые случаи типа ref [struct]). Ну, чтож.

Возможно не стоит, а возможно и стоит - написание руками класса с полем и методом, повторяющим то, что сделал бы компилятор для лямбды - это разумно/упрощает/стоит того?

Я склоняюсь к тому, что универсального ответат нет, зато выбор есть.

Про замыкания, ну бокс бог с ним - не будем называть это прямо "боксингом"

Не "не будем", а "нельзя".

Боксинг - хоть в .НЕТ, хоть в абстрактном CS-определении - это не "копировние из стека в кучу" и кроме аллокации тянет за собой и вычислительные расходы.

В случае с захватом этого не происходит.

Более того, и самой локальной переменной на стеке вообще [в большинстве случаев] не окажется, она сразу будет определена в классе, созданном компилятором для лямбды.

но факт, что (возможно, нежелательное) копирование из стека в кучу при замыкании вполне возможно

Не "вполне возможно", а обязательно произойдёт, бай дизайн, так сказать.

только без личностей, хорошо? ... не знаю ваш возраст

Ноль вопросов, никаких личностей, просто я (лично) считаю, что учиться никогда не поздно и не зазорно, а иногда ещё и нужно ;)

Boxing возникает неявно на инструкции IL_0010

Вообще, не сказал бы, что прям неявно:

https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-8.0&redirectedfrom=MSDN

When a callvirt method instruction has been prefixed by constrained thisType, the instruction is executed as follows:

  • If thisType is a reference type (as opposed to a value type) then ptr is dereferenced and passed as the 'this' pointer to the callvirt of method.

  • If thisType is a value type and thisType implements method then ptr is passed unmodified as the 'this' pointer to a call method instruction, for the implementation of method by thisType.

  • If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed, and passed as the 'this' pointer to the callvirt method instruction.

This last case can occur only when method was defined on ObjectValueType, or Enum and not overridden by thisType. In this case, the boxing causes a copy of the original object to be made. However, because none of the methods of ObjectValueType, and Enum modify the state of the object, this fact cannot be detected.

Но ок, box в IL действительно нет, спасибо за напоминание.

Тем не менее, что насчёт обсуждаемого случая?

Есть там цитата?

Отлично, первые шаги к изучению учебника сделаны.

Вот, можете ознакомиться,

А можно теперь конкретную цитату, которая относится к обсуждаемому случаю?

boxing есть, но явная инструкция box в IL отсутствует.

Любопытно было бы увидеть примеры, не поделитесь?

...но это, к примеру, легко доступная элементарная оптимизация:

Объявляем локальную переменну, объявляем лямбду, которая её захватывает.

В цикле n раз изменяем значение переменной и вызываем метод, в который передаём лямбду - итого одна аллокация вместо n

Всё может быть чревато :)

С "проблемой цикла" можно научиться жить, а вот невозможность изменять захваченную переменную - мне бы мешало.

А что же по-вашему такое тогда боксинг? :-О

А вот это можно почитать и в учебнике.

Жаль нельзя на большие деньги поспорить, погулял бы на НГ за чужой счёт в кои-то веки.

Повторю: боксинга нет, ref struct захватывать нельзя по другой причине (да, именно из-за отъезда в кучу).

"Уезжать в кучу" != боксинг.

нет там никакого боксинга.

Большое спасибо.

А можете добавить в бенчмарки измерение аллокаций и GC?

Справедливости ради, факт встречи человека, который вообще рассматривает вариант перемещения по Женеве за рулём, а не на общественном транспорте (на крайняк такси) тоже достаточно неожиданный ;)

Буду благодарен.

ОпенВПН сервер на ОпенВрт тоже поднять совсем несложно, очень бы помогло, если и его сможете протестировать.

А можете побенчмаркать, сколько он через OpenVpn и Wireguard сможет прокачать? В качестве сервера и в качестве клиента?

Я тоже планирую подобное собрать, пытаюсь определиться с процессором, в идеале чтобы хватило полностью забить как минимум 1 гигабит (а то и 2.5 в пике), при этом держать 2-3 впн-сервера для 4-8 клиентов и 2-3 клиентских подключения к сторонним ВПН-серверам.

Вообще, 150 Мбит это очень скромно, если не сказать прямо: неприемлимо мало.
Сам пытался найти бенчмарки чтобы подобрать железо — нереально.

Информация

В рейтинге
4 733-й
Зарегистрирован
Активность