C# (C Sharp) programming


Гео и язык канала: Россия, Русский
Категория: Технологии



Гео и язык канала
Россия, Русский
Категория
Технологии
Статистика

Аллокации, которых нет в коде: охота на скрытый боксинг в .NET 10

Самая дорогая аллокация в вашем сервисе та, которой нет в исходниках. Вы написали struct ради zero-allocation, прошли code review, а в проде Gen0-коллекции все равно идут косяком. Потому что между вашим кодом и машинным кодом стоит компилятор, и он молча упаковывает ваш value-тип в кучу там, где вы этого не просили — а на код-ревью этого не видно.
TL;DR. Боксинг (boxing) в .NET - это не только object o = 42. Он прячется в вызовах интерфейсных методов на struct, в дефолтном ValueType.Equals, в params object[]-аргументах, в foreach по интерфейсу и в замыканиях. При этом часть “классических” примеров боксинга из старых гайдов на современном рантайме уже не аллоцирует — JIT научился их вырезать, и слепо копировать советы десятилетней давности вредно. Ниже — карта мест, где боксинг живёт и сейчас, отдельный разбор того, что рантайм уже оптимизировал, реальный мини-кейс, воспроизводимый бенчмарк на BenchmarkDotNet с MemoryDiagnoser, способ ловить упаковку через DOTNET_JitDisasm и dotnet-gcdump, и паттерны лечения без потери читаемости.
О версиях и числах. Всё прверялось на .NET 10 (текущий LTS) и C# 13/14-уровне компилятора, Release, без отладчика, BenchmarkDotNet с MemoryDiagnoser. На .NET 8/9 поведение в основном такое же, но отдельные оптимизации JIT отличаются между мажорными версиями — поэтому главный принцип статьи: не верьте на слово (в том числе мне), гоняйте MemoryDiagnoser на своей версии рантайма. Числа в таблицах ниже - иллюстративные, порядок величины, а не точные замеры с вашего железа.
Пролог: “у нас же всё на struct, откуда Gen0?”
Сервис на горячем пути считает метрики: миллионы маленьких readonly struct-значений в секунду, никакого new, никаких классов в hot path. По задумке — ноль аллокаций. На дашборде — стабильный поток Gen0-коллекций раз в несколько секунд под нагрузкой.
Профайлер показывает аллокации, но стек ведёт в метод, где в коде нет ни одного new. Там цикл по интерфейсу, пара вызовов .Equals(), передача значения в params-метод лога. Глазами — чисто. В машинном коде — box-инструкции на каждой итерации.

Это и есть скрытый боксинг: компилятор C# и JIT упаковывают ваш struct в объект на куче, потому что в конкретной точке кода value-тип нужно представить как ссылочный. Симптом — Gen0-коллекции “из ниоткуда”, и его не видно ни в code review, ни в дампе, пока не посмотришь на IL или дизасм.

Что такое боксинг и почему он стоит дорого
Боксинг — это упаковка value-типа (struct, enum, примитив) в объект на управляемой куче. Рантайму нужно выделить заголовок объекта, скопировать туда значение и вернуть ссылку. Анбоксинг - обратная операция с проверкой типа.
Цена не в самой инструкции, а в последствиях: каждая упаковка - это аллокация в Gen0. Много мелких аллокаций на горячем пути означают частые Gen0-коллекции, паузы (пусть и короткие), вытеснение полезных данных из кэша и общий рост CPU на ровном месте. На сервисе с SLA по p99 это бьёт по хвосту латентности так же, как и любая другая лишняя аллокация.

В IL боксинг виден явно - инструкция box. Именно её мы и будем искать.
Читать дальше: https://habr.com/ru/articles/1049236/


🖥 C# Roadmap: с нуля до профи

Практическое руководство по росту в C#-разработке. Материал собран для тех, кто хочет получить инженерную глубину, а не просто накликать CRUD по туториалам. 

Здесь последовательность изучения, лучшие практики, ресурсы и трезвый разбор того, как работать с ИИ-инструментами и оставаться востребованным.

https://github.com/Develp10/Csharp_Roadmap/


Видео недоступно для предпросмотра
Смотреть в Max
Unity 6 заходит в эпоху AI-геймдева: ИИ-агент теперь прямо в редакторе

Unity выкатила в открытую бету AI-помощника, который работает не как «чатик сбоку», а как полноценный агент внутри проекта. Он видит контекст сцены, понимает структуру кода и может сам вносить изменения.
Что умеет:
— Plan Mode: разбивает задачу на шаги, пишет код, ищет ошибки и помогает выстроить архитектуру
— Figma-интеграция: можно дать ссылку на макет, а Unity попробует собрать по нему интерфейс
— Генерация ассетов: текстуры, звуки и 3D-объекты можно создавать по текстовому описанию
— Откат изменений: если агент накосячил, правки можно быстро вернуть назад
Для Pro и Enterprise функции уже доступны. В Personal-версии бету можно попробовать через trial.
Геймдев постепенно превращается в работу не только с кодом и сценами, но и с агентами, которые собирают часть проекта по описанию.
А вместе с этим, похоже, нас ждёт новая волна нейрослоп-игр в Steam.

https://unity.com/features/ai?utm_campaign=unity-ai-beta


🚨 Тихий убийца производительности в EF Core, о котором забывают почти все.
Запрос выглядит идеально - пока у тебя мало данных. Потом начинается ад.
Ты пишешь обычный Include, потом ещё один на ту же сущность… и не замечаешь, как EF Core превращает это в монструозный SQL с кучей JOIN’ов.
Что происходит под капотом:
EF делает несколько JOIN’ов → получается cross product → строки начинают дублироваться
Итог:
• данных в ответе становится в разы больше
• память улетает
• запросы резко тормозят
И всё это без единой ошибки в коде.
Решение есть и оно банально простое - Query Splitting.
Вместо одного жирного запроса EF разбивает его на несколько аккуратных. Без дублирования, без раздувания результата, без боли.
Одна настройка - и ты экономишь кучу ресурсов на проде.
P.S. Если работаешь с EF Core - такие нюансы решают, будет ли твой сервис летать или умирать под нагрузкой.


🔥 Самая недооценённая фича HttpClient в .NET
DelegatingHandler - это middleware для исходящих HTTP-запросов, про который многие забывают.
По сути, ты собираешь pipeline для запросов так же, как в ASP.NET
для входящих.
И вместо того чтобы пихать логику в каждый вызов, выносишь всё в одно место.
Авторизация, логирование, ретраи, кеш, аудит, всё навешивается как цепочка обработчиков.
Код становится чище, повторного кода меньше, а поведение запросов контролируется централизованно.
Один раз настроил  и это работает для всех клиентов.
Если используешь HttpClient и до сих пор не трогаешь DelegatingHandler, ты реально упускаешь мощный инструмент


🚀 5 вещей, которые я добавляю в каждый .NET проект
Если сделать это сразу - потом не будешь страдать в проде
1️⃣ .editorconfig / .props  
Автоматически фиксируют стиль кода  
→ меньше споров, больше консистентности  
2️⃣ Статический анализ  
SonarAnalyzer и аналоги  
→ ловят баги ещё до запуска  
3️⃣ Наблюдаемость (Observability)  
Serilog + OpenTelemetry  
→ логи + трейсы = понимаешь, что реально происходит  
4️⃣ Docker Compose / .NET Aspire  
Поднимаешь всё окружение одной командой  
→ БД, кеши, очереди  
5️⃣ CI/CD с первого дня  
Авто-сборка и тесты  
→ не даёшь сломанному коду попасть в main  
Настроил один раз  
→ экономишь десятки часов потом  
🔥 Самое сложное для большинства - Observability  
но именно оно спасает в проде


⚙️ Как правильно работать с настройками в .NET?
В .NET есть 3 основных интерфейса для конфигурации.  
И если выбрать не тот — приложение может просто игнорировать изменения в настройках.
Разбираем просто 👇
1️⃣ IOptions  
- читается один раз при запуске  
- кэшируется на всё время жизни приложения  
- подходит для статических настроек  
2️⃣ IOptionsSnapshot  
- пересчитывается на каждый запрос  
- подхватывает изменения в appsettings.json без перезапуска  
- идеален для Web API (Scoped)  
3️⃣ IOptionsMonitor  
- обновляется в реальном времени  
- триггерит событие при изменении настроек  
- подходит для фоновых сервисов (Singleton)  
Главное правило:
👉 статические настройки → IOptions  
👉 веб-приложения → IOptionsSnapshot  
👉 фоновые сервисы с реакцией на изменения → IOptionsMonitor  
Если используешь не тот интерфейс — можешь долго не понимать, почему конфиг не обновляется.
А это одна из самых частых и незаметных ошибок в .NET.


Полезный паттерн для Minimal APIs в .NET, если вы хотите организовать проект по принципу Vertical Slice Architecture.
Идея очень простая.
Вместо того чтобы держать все роуты в Program.cs, каждый endpoint выносится в отдельный класс. Что это даёт:
• endpoints изолированы по фичам
• код становится намного чище
• проще масштабировать API
• удобно использовать вместе с CQRS / MediatR
Регистрация таких endpoints занимает буквально пару миллисекунд при старте приложения.
Отличный способ держать Minimal API структурированным даже в больших проектах.


Разработчик показал, как использовать **Ollama для извлечения данных из чеков прямо в .NET**.
Самая интересная часть оказалась не в том, чтобы отправить изображение модели.
Гораздо сложнее было **получить результат, который можно реально использовать в коде**.
Обычный текстовый ответ мало помогает, когда нужны структурированные данные:
- позиции из чека
- количество
- цены
- итоговая сумма
Поэтому вместо обычного ответа модель начали просить **возвращать JSON**.
После этого результат можно сразу **маппить в C#-объекты** и использовать в приложении.
И именно здесь начинается самое интересное.
Большая часть работы — **не код**, а **правильный prompt**.
Если модель:
- округляла цену
- пропускала цифру
- или «придумывала» позицию
приходилось уточнять инструкции.
Это и есть главный сдвиг в таком подходе:
раньше разработчик писал парсеры и regex,
а теперь — **настраивает поведение модели через prompt**.
Когда модель начинает возвращать **структурированные данные**,
всё остальное снова превращается в обычный код приложения.
Разбор полной реализации:
https://milanjovanovic.tech/blog/how-to-extract-structured-data-from-images-using-ollama-in-dotnet
#ai #ollama #dotnet #csharp


Vector Search - как это работает (и почему это важно для .NET разработчиков)
Vector search ищет смысловую близость, а не просто точные совпадения.
Он сравнивает данные - текст, изображения или аудио - используя векторные эмбеддинги в многомерном пространстве.
То есть система ищет не одинаковые слова, а похожие по смыслу объекты.
Почему это важно?
Vector search лежит в основе многих AI-функций:
- семантический поиск  
- рекомендательные системы  
- интеграции с LLM  
- умные ассистенты внутри приложений  
Добавив векторный поиск в приложение, разработчик может создавать намного более умные продукты, которые понимают смысл запросов пользователя.
Это дает реальную бизнес-ценность - от поиска по документам до персонализированных рекомендаций.
📍 Полный пример реализации


C# (C Sharp) programming
Канал создан

Показано 11 последних публикаций.

426

подписчиков
Статистика канала