C# Heppard
1.56K subscribers
74 photos
2 files
122 links
25 способов эффективно использовать .NET

Поддержать канал можно тут: https://sponsr.ru/sharp_heppard
Download Telegram
Отвыступал. Надеюсь, получилось интересно.
🔥274👍1
Оказывается, презентацию c DotNext выступления можно скачать тут. Видео будет через полгода.

#выступления
🔥74👏2
Кстати, хотел с вами поделиться хорошим обзором книги Конрада Кокосы Pro .NET Memory Management. Обзор для начинающих, то есть тех, кто вообще не особо в теме того, что написано в книге и кто такой Конрад. Степан, увы, не специализируется на производительности, но очень хорошо рассказывает.

https://www.youtube.com/watch?v=cXbZrLNSPvY

#память
👍9🤔2
После недавнего инцидента на проде, захотелось пересмотреть видео "Коленька, ты чо задеплоил". Не совсем про перформанс. Вернее, совсем не про перформанс.

https://www.youtube.com/watch?v=K6oZuB8_dU8

#отдых
👍42🔥1
Rust глазами дотнетчиков #лекция #rust

Набор подкастов по Rust от C# разработчиков. Парни хохмят, пытаются объять предысторию и делятся мнениями. Из минусов - очень долго, но мне такое нравится. Если интереснее более классическое изложение материала, то Кладов до сих пор очень крут.

Если приятнее читать, а не слушать, то можно сходить вот сюда.
👍9
Проблемы ситибилдера #игра #скорость #память

Я очень люблю градостроительные симуляторы. Выход Cities: Skylines 2 дал мне возможность слегка по иному взглянуть на этот тип игр. А именно, с точки зрения "преждевременная оптимизация это зло". Кажется, что мужики по полной использовали этот спорный тезис, так как игра выдаёт весьма скромные результаты при весьма не кислом потреблении ресурсов.

У меня достаточно хороший ноут, который тянет RDR2, Киберпанк и кривой порт tLOA. На весьма хороших настройках. А вот Cities: Skylines 2 тормозит.

Вот тут коллега пытается разобраться, а в чём, собственно, дело.

https://habr.com/ru/articles/772082/
https://habr.com/ru/articles/772284/

P.S.: И да, дело не в ECS (в Unity оно называется DOTS), а в банальном... я даже не знаю... пофигизме к производительности. Мужики делали игру про город, где графика как бы не так уж и важна, и смогли наступить почти на все графические грабли. Печально. Радует, что поправимо.
🔥7😁2👍1
Scoped в Singleton #отдых #архитектура

Я вот помню, на собесах спрашивали - можно ли Scoped звать из Singleton.
Так что, получается, можно или нет?

var provider = new ServiceCollection()
.AddScoped<Scoped>()
.AddSingleton<Singleton>()
.BuildServiceProvider();

provider.GetRequiredService<Singleton>();

public class Scoped
{
public string Say() => "Scoped in Singleton";
}

public class Singleton
{
public Singleton(Scoped scoped)
{
Console.WriteLine($"{scoped.Say()}, World!");
}
}
😁6👍3🤯2
Медленное интернирование #память #бенч

Есть вот такое мнение при интернировании строк. Если вам нужно быстро, то надо в ConcurrentDictionary, а не string.Intern(x). Код бенчмарка внутри.

Недавно это разбирал некий Сергей Тепляков, а какой-то Евгений Пешков писал.
👍7🤔4
Проверка существования значения #бенч #скорость

А вот ещё один интересный бенч. Есть такой паттерн - проверка существования значения в переменной с помощью расширения "TryGet". Мол, если у нас оно есть, то true, а иначе false.

Ну то есть удобно сделать так:

if (id.TryGet(out var existsId)) query = query.Where(dbo => dbo.Id == existsId)


Есть моментик. Можно написать наиболее общую штуку, которая делает instance.Equals(default), а можно конкретное написать instance == Guid.Empty. Второе сильно быстрее.
🤯32
Работа с Excel #решение #память

Нашёл тут очень интересную библиотеку для работы с xlsx.

Пока первые результаты очень впечатляющие. Однако, судя по коду, человек просто сделал хорошо. Кажется, можно сделать лучше, но про это я пока промолчу - нет данных.

В целом же, рекомендую для рассмотрения замены EPPlusFree и ClosedXML, если у вас есть проблемы с производительностью. Или, например, памятью. Я это к чему. В EPPlus у нас файлик в 20 мб внезапно распаковался в какое-то страшное количество мегабайтиков, и мы упали с OutOfMemoryException.
🔥9👍4
Коллеги, если кто-то ходит в ClickHouse c помощью библиотеки у которой больше всего звёзд в github, то я вас немного расстрою. Кажется, это всего-лишь обёртка над HTTP. Причём не самая быстрая. Напомню, что ClickHouse поддерживает тот же GRPC.

#решение #хранилище
Продолжая тему с HTTP, хочется напомнить, что Trino поддерживает HTTP. Ну если вдруг вы не знаете, как к нему легко подключиться.

#решение #хранилище
Поиск пути #игра #алгоритм #память

Есть такой алгоритм, называется A-Star (A*) - он нужен для поиска оптимального пути в 2D пространстве. Если вы не знали, то для него есть хорошая штука в базовых коллекциях .NET, называется PriorityQueue (завезли в .NET 6). Мотивация, в принципе, была очевидна - очень востребованная коллекция в играх (привет Unity).

Очередь с приоритетами - основной элемент алгоритма поиска пути. Когда я отчаиваюсь писать для энтерпайза и начинаю писать свою стратегическую игру, я снова и снова воспроизвожу A*. Про очередь с приоритетами недавно писал некий Степан, а до него писали вот тут.

Кстати, этот же алгоритм очень полезен на собеседованиях, где есть алгоритмическая секция. Например, знание устройства очереди с приоритетами помогало мне на собесах в Яндекс или Тинькофф.
🔥10👍5
Копирование массива #скорость #бенч

А вот Array.Copy. Мы можем соревноваться с ним в виде поэлементного копирования массива или, даже, сделать буффер на стеке через stackalloc и пытаться перемещать через него.

Увы, не поможет. Array.Copy будет быстрее за счёт, например, memmove. Там есть ещё пара ухищрений, но я рекомендую посмотреть их лично, перейдя к исходникам.

По вопросам реализации в своё время был интересный тред на github. Там такая масса подробностей, что мозг может задымиться.

Для нас это всё должно значить примерно следующее: по возможности нужно использовать Array.Copy (пусть даже это в виде stream.ReadAsync(buffer), а не писать велосипеды в виде побайтного копирования потока.
👍9🔥4
Доказательство существования поколений #отдых #бенч #память

Помню, на одном собесе меня попросили доказать наличие нескольких поколений памяти в .NET. Я изобразил вот такое, отталкиваясь от знаний, какие объекты попадают в LOH. Может быть кому-то понадобится.


[SimpleJob(RuntimeMoniker.Net80)]
[MeanColumn, MemoryDiagnoser]
public class LohArray
{
[Params(84900, 85000)] public int Length { get; set; }

[Benchmark]
public int LohIliNet()
{
var array = new byte[Length];
return array[0] % 2;
}
}

Сегодня я пересматриваю А.Жмур (Pragmatic memory management) и, о чудо, внезапно вспомнил, откуда я взял этот код. Как интересно работает память человека. Как в .NET)
👍13🤯4
Static в анонимных функциях #отдых #бенч

Представляется, что ключевое слово static в анонимных функциях - декларация о намерениях, не более. То есть мы как бы говорим, что по нашему мнению в данном месте точно не надо захватывать контекст и создавать объект аллокации. Бай дизайн типа.

Т.е. это не про скорость и аллокацию тема.

Код бенчмарка в чатике.

Ещё почитать про это можно в соседнем канале.
👍114
Графика для самых маленьких #графика #лекция #игра

Рекомендую хороший набор роликов по OpenGL. Лектор явно с математическим складом ума, много рассказывает о том, как это должно работать, а потом реализует в коде. Примеры с использованием OpenTK. Есть и примеры с Monogame.
👍11
Докупить память или написать эффективно? #отдых

05.03.2024 в рамках процесса *оптимизации* использования ресурсов кластера kubernetes (***) будут выключены сервисы, развернутые в следующих неймспейсах...


Когда я получаю подобные сообщения от корпоративной инфраструктуры, либо от команды RE, я всегда вспоминаю один диалог. Состоялся он, ох, уж сколько лет прошло, на одном локальном митапе. Я, как всегда, вещал про то, что было бы неплохо писать оптимальный код, в том смысле, чтобы экономить байтики и наносекунды. То да сё, слайды, смешки, лёгкое непонимание в глазах слушателей. Наконец, секция вопросов и ответов.

Я хорошо помню этого мужика, который во время доклада делал фейс-палмы, громко ёрзал стулом, сидел в телефоне. Я ждал вопросов от него и дождался.

- Скажите, а зачем всё это?
- В смысле, - не понимаю я.
- В том смысле, - сказал он авторитетно, - что это всё не нужно. Проще купить плашку в 16 ГБ памяти, чем всё это знать.

Я тогда был молод, поэтому мой ответ был слаб. Жаль. Мне кажется, что в тот момент некоторые люди разочаровались в теме. Теперь я умный, теперь я знаю что ему ответить. Ну про то, что у нас k8s, 800m процессора и 2048Mi памяти. А чтобы просить больше, надо согласования, утверждения и вообще.

Где этот дядя с 16 ГБ настоящей оперативки и, наверное, с двумя-тремя настоящими ядрами?
Отдай мне их, дядя, я всё прощу.
👍15😁11🤯1
Читая некоторые параллельные каналы а-ля .NET Разработчик или StepOne, я иногда удивляюсь. Мне кажется, коллеги иногда не внимательно слушают RadioDotNet. В очередной раз хочу его прорекламировать.

Это подкаст про:
- Новости мира .NET.
- Новинки языка C#.
- Новинки ASP.NET, EF и прочего.
- Новинки популярных библиотек.
- Обзоры статей известных авторов о мире .NET.

К каждому выпуску прикреплены статьи, код на github, всякие разные ресуры, по которым очень интересно ходить.

Для состоятельных парней, есть возможность поддержать Анатолия и Игоря на boosty. За это присылают подарки, дают доступ к болталке и ко всяким записям вне выпуска. Иногда там бывает интересно. Ребята молодцы, делают хорошее дело.

Считаю RadioDotNet одним из лучших каналов для получения оперативной информации о мире .NET.

P.S.: А вот этот канал, кажется, опережает даже RadioDotNet. Евгений молодец. Будь как Евгений.
P.P.S: И как Сергей и Степантут) тоже будь. Я вот их немного подначиваю, но они хорошие!

#лекция #статья
👍18🔥2
Свой ConcurrentDictionary #память #лекция

Кстати, ещё один камень в огород тех, кто считает, что проще купить плашку памяти, чем заняться оптимизациями.

Это скриншот из доклада Антона Нечуговских (Контур) по поводу своей собственной имплементации ConcurrentDictionary. Только и нужно - инструменты анализа, знание устройства словарей, знание модели памяти, понимание профиля нагрузки, аккуратный код.

Как результат: потребление памяти в кластере снизилось на 30-40%. Неплохо так сэкономили. Я не знаю сколько это в деньгах, но то, что они сэкономлены - нет никаких сомнений.
👍21🔥7👎1
Несколько solution в одном Rider #решение

Ого, я не знал, что в Rider можно подключить несколько проектов из разных репозиториев, и они будут работать нормально. То есть изменения каждого проекта пойдут в свои репозитории.

Подключаем как Existing project, перезагружаем IDE (не знаю зачем, но надо) - вуаля. Иногда есть какое-то странное поведение - не получается ткнуть и переключиться на нужную ветку. Но, в целом, пользоваться можно.

Чтобы редактировать проекты локально и не связываться с пушингом в nuget каждого изменения, подключаем библиотеки вот так:


<ItemGroup>
<PackageReference
Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"
Include="***.Data"
Version="1.0.1"/>
<ProjectReference
Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"
Include="..\..\локальный_путь.Data.csproj"/>
</ItemGroup>


То есть в релизе будет библиотека из nuget'a, а в debug - локальная копия.

P.S.: Удалить проект можно в настройках: Version Control -> Directory Mappings. В окне нажимаем минусик, чтобы удалять репозитории.
🔥15👍4👎1🤯1