gram news
C# Heppard channel avatar

C# Heppard

@csharp_gepard

25 способов эффективно использовать .NET Поддержать канал можно тут: https://sponsr.ru/sharp_heppard

ProjectsRUProgramming

1,650subscribers

Open the Channel

Latest posts

  • C# Heppard

    13 Mar, 10:27

    forwarded from @ozon_tech

    Ozon Tech Community .NET Meetup24 марта, лофт Casa Picassa, 19:00 Ищем способы бороться с primitive obsession, отличать OrderID от ItemID, переживать нагрузку без каскадных отказов с load shedding и спасаться от аллокаций с помощью JIT-оптимизатора ❕➡И находим: вас ждут три доклада — немного про runtime-внутрянку, немного про хайлоад-сервисы, много-много кейсов из нашей .NET-практики.Когда трансляция подойдёт к концу, мы с вами, офлайн-гостями, останемся на импровизированной кухне — обсуждать спорные и неудачные решения без камеры, логов и трассировки. До утра вряд ли, но до глубины души наверняка.Есть ощущение, что места закончатся через 3…2…1… Так что не тяните с регистрацией ⬅️#ozontech_events #csharp
    Image from a post by C# HeppardImage from a post by C# Heppard
    1,75086431Open in Telegram
  • C# Heppard

    20 Jan, 15:27edited

    Ещё одна история про память #отдыхСудя по комментариям специалистов и ценам на RAM в магазинах, историю про память я буду рассказывать снова и снова. Это, конечно, не смищно.Но есть новая история.Недавно сосед предложил прийти к нему и посмотреть, а что ж у него с новым компом. Он прям вот вчера его купил. Не включается, не пищит, вообще не подаёт признаков жизни.Ну да, я же программист, я понимаю в компах. Для важности взял чемоданчик с инструментами. Ну где у меня лежат разные отвёртки, плоскогубцы и молоток.Пришёл, потыкал кнопку "вкл" и даже "ресет". Не помогло. Открыли корпус, осматриваю красивые внутренности. Корпус красивый, богатый, с "любимой" подсветкой. Видюха внушительная, процессор мощный такой, солидный. Провода разноцветные. И две плашки памяти, аж 64 Гб.Они мне сразу показались подозрительными. Я не часто видел плашки памяти, но явно не гуд, когда они как бы
    TelegramC# HeppardДокупить память или написать эффективно? #отдых 05.03.2024 в рамках процесса *оптимизации* использования ресурсов кластера kubernetes (***) будут выключены сервисы, развернутые в следующих неймспейсах... Когда я получаю подобные сообщения от корпоративной…
    2,4201061Open in Telegram
  • C# Heppard

    25 Nov 2025, 06:31edited

    FastEnum #скоростьИногда нам нужно не просто быстро, а очень быстро. В этот момент в дело вступают самые необычные оптимизации. Например, оптимизация работы с enum. Типичный сценарий - получить строку из enum'a или, наоборот, enum из строки.Многие знают, что получение строкового представления enum'a лучше делать через Enum.GetName(MyEnum.Value), а вариант MyEnum.Value.ToString() аллоцирует новую строку и несколько медленнее.В случае сложной логики получения строкового представления enum'a, чаще всего используется кэш (который, кстати, есть в Enum.GetName). Для этой цели можно написать свой класс, который содержит два словаря. В случае получения строки из enum'a мы идём по одному словарю, а в случае получения enum'a из строки - по другому. Код примерно такой: private static readonly FrozenDictionary<string, T> StringToValues; private static readonly FrozenDictionary<T, string>
    2,910201021Open in Telegram
  • C# Heppard

    20 Nov 2025, 06:58edited

    UnsafeAccessor #скоростьИногда возникает странное желание изменять приватные поля в классах, код которых нам не доступен. Например, внутренний массив коллекции или настройку, которая почему-то и, по нашей логике, возмутительно не выставлена наружу.В этом, не самом здоровом желании, нам, конечно, поможет reflection. Код будет тривиальный, что-то вроде typeof(Entry).GetField(...) . Этот код найдёт поле в типе и вернёт нам его объектное представление.Особо упорные ребята могут делать подобную операцию каждый вызов метода, но это крайне не оптимально на горячих участках кода. Более умные коллеги выполнят поиск поля один раз, положат его в статическую переменную и будут получать значение через fieldInfo.GetValue(_entry), а задавать через fieldInfo.SetValue(_entry, value).Те, кто читал про ExpressionTree, вполне резонно будут получать и задавать значение через заранее сформированные
    2,40030105Open in Telegram
  • C# Heppard

    17 Nov 2025, 13:23edited

    Latency numbers every programmer should knowЯ всё время теряю эти циферки, особенно когда они нужны в процессе ожесточённой беседы про производительность. Забываю ключевые слова для поиска, нахожу не те картинки.А ведь эти циферки очень полезны для всех, кто так или иначе интересуется производительностью. Эти цифры и картинка иллюстрируют, что, например, поход в БД значительно более приоритетная цель для оптимизаций, чем, например, замена List на Dictionary. Или что сеть может съесть все перформансные улучшения, связанные с переходом на struct и Span.Не забывайте про эти цифры, когда исследуете проблемы с производительностью. Смотрите на то, что реально тратит время (или память).Взял отсюда, а ссылаются ещё вот сюда.P.S.: Сами цифры вызывают вопросы, но в том, что их отношение друг к другу примерно такое - сомнений нет. P.P.S: Коллега ещё напоминает о стоимости операций. L1 cac
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,050293Open in Telegram
  • C# Heppard

    29 Oct 2025, 08:33edited

    Dictionary.TryGetValue #скоростьУж сколько лет прошло и, вроде, все это знают. Но, тем не менее, периодически на собеседование приходит человек, который пишет не оптимальный код извлечения значения из словаря. Я увидел, что я про это не писал, поэтому напомню ещё раз это элементарное правило.Коллеги, если у нас есть сценарий: проверить существование ключа в Dictionary и извлечь соответствующее ему значение, то не надо делать ContainsKey, а потом извлекать значение. В словаре есть прекрасный метод TryGetValue, который проверяет наличие ключа и, если он есть, тут же, не отходя от кассы, извлекает значение. Это быстрее примерно на 20-30%.А почему использование TryGetValue быстрее? Ведь поиск в Dictionary это O(1), типа очень быстро. Но надо вспомнить, что O(1) это алгоритмическая сложность, не абсолютные цифры. Это про то и только про то, что скорость поиска не зависит от количества
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,460421Open in Telegram
  • C# Heppard

    27 Oct 2025, 13:45edited

    Надо тренироваться #отдыхПриехали фото с конференции. Я что-то толстоват. Поэтому понял, что надо усилить тренировки. Я хожу на спорт уже полгода и мне очень нравится: чистит мозги, рабочий перформанс лучше.Это перекликается с песней моего детства о пиратах из "Остров сокровищ", где говорилось, что в здоровом теле - здоровее дух. Ну и вообще, Джим молодец, потому что утром делает зарядку.Так вот. Тренер, которого, на самом деле, зовут Денис (я его называю "Тренер", как героя фильма "Джентельмены")... был на конференции мысленно (знал что она будет, видел фотки), и предложил больше тренироваться, чтобы выглядеть перформить лучше. После тренировки чувствуешь, что можешь свернуть горы. Не в первый день, конечно, так как в первый день хочется спать.Если кто из Нижнего Новгорода, сходите к Денису - он крутой тренер. Не жестит, осторожно и грамотно подходит к тренировкам, мотивирует.
    1,930video1111521Open in Telegram
  • C# Heppard

    20 Oct 2025, 06:37edited

    Function pointer #скоростьПредставим, что у нас есть подсистема вычисления. Один класс отвечает за выбор операции над значениями, а другой производит магию вычисления с использованием выбранной операции. В каждом из классов какая-то сложная логика, поэтому объединить их нельзя или сложно.Пример: операции над формулами в Excel - до того как мы прочитаем формулу, мы не знаем, какая операция будет произведена над ячейками.Условно, это выглядит вот так: MathOperation operation = SelectOperation(Context);Func<int, int, int> executor = operation switch { MathOperation.Add => MathOperations.Add, MathOperation.Subtract => MathOperations.Subtract, MathOperation.Multiply => MathOperations.Multiply, MathOperation.Divide => MathOperations.Divide, _ => Error.NotSupported(operation, Context) };Calculator.Execute(executor, xValue, yValue);Это работает быстро, но, благодаря "современному"
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,2101512111Open in Telegram
  • C# Heppard

    13 Oct 2025, 15:03edited

    Unsafe.SkipInit для структур #скоростьКак раз на конференции, в кулуарах, спрашивали про Unsafe.SkipInit. Набросал бенчмарк, который будет в комментариях.Как я уже говорил, это решение следующей проблемы: 1. Выделяется память. 2. Эта память заполняется дефолтными значениями (чтобы программист не получил в значениях полей структуры явную тарабарщину от предыдущих пользователей памяти). Условно 0000000000. 3. Память, в виде структуры, отдаётся пользователю (программисту). В классическом варианте, программист получит в числовом поле 0 (deafult), а в ссылочном - null.Вот Unsafe.SkipInit говорит, мол, господин рантайм, я и сам заполню все значения. Ну или, в смысле доклада, я и сам знаю какая область памяти мне нужна как инициализированная. То есть п.2 не выполняется. Что заметно улучшает скорость. Документация тут, там есть интересные примеры.Кстати, обратите внимание на разницу в
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,210183Open in Telegram
  • C# Heppard

    13 Oct 2025, 14:02edited

    Сезон кода в Нижнем НовгородеОтвыступал на "Сезоне кода" (организатор Т-Банк). Я давно не ходил на конференции, давно не выступал. Мне очень понравилось. Хорошие темы, интересные спикеры.Участники конференции задавали много вопросов, затем обсуждение переместилось в кулуары. Это всегда очень здорово и приятно - побеседовать с коллегами, которые давно в теме доклада, которые смотрят на твои проблемы под другим углом, имеют свой опыт, свои решения. Супер.Ещё из плюсов конференции: трёхразовое питание, много активностей (от решений задач до карьерных консультаций) и афтерпати. Огромные экраны, просторный зал, отличная акустика и звук. Ух! Жаль, что не будет записей докладов - я бы хотел посидеть над некоторыми вдумчиво.Спасибо организаторам!Презентация тут.
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,10014632Open in Telegram
  • C# Heppard

    7 Jul 2025, 19:33

    forwarded from @are_you_teamlead

    Image from a post by C# HeppardImage from a post by C# Heppard
    3,16044822Open in Telegram
  • C# Heppard

    27 Jun 2025, 11:34edited

    Маленький словарь #скорость #памятьЧасто бывает, что мы получаем данные из внешнего источника или БД, создаём временный словарь, ищем по нему, а потом про него забываем. Часто бывает, что приходящих данных мало, например, 10-15 элементов.При этом, многие помнят, что поиск по словарю при небольшом количестве элементов не всегда эффективен (поиск по массиву будет быстрее). Также, те коллеги, которые помнят устройство Dictionary, могут вспомнить, что эта структура данных имеет два внутренних массива, выделение которых на горячих направлениях кода может вызвать неплохой memory pressure. Например, создание одного словаря размером в 10 элементов - почти 1кб памяти.В принципе, решение задачи лежит на поверхности.Необходимо создать такую структуру данных, которая бы с самого начала хранила данные в массиве, а, в случае большого количества элементов, переходила на честный словарь, чтобы
    Image from a post by C# HeppardImage from a post by C# Heppard
    3,820216Open in Telegram
  • C# Heppard

    26 Jun 2025, 09:12edited

    JsonPath в .NET #решениеПредставим себе, что есть сервис, который умеет получать данные из Kafka и складывать полученные данные в БД. Без программирования, просто декларативным указанием topic и таблицы в БД. То есть:1. Сервис работает по запросу (job или unit-of-work). 2. При создании job описывается маппинг данных из Kafka в нужную таблицу. 3. Описывается фильтрация и преобразовывает данных из Kafka так, как пользователю удобно. Ну чтобы не заниматься этим при каждом запросе в БД.То есть, во-первых, нужен вменяемый API, которым удобно пользоваться. Во-вторых, нужно описание маппинга полей сообщения из Kafka в поля Data-base-object (DBO). Ну и всякая фильтрация (например, отсечение удалённых), выбор определённых полей и некие операции над ними.Например, нам нужно взять подразделения компании, перенести часть нужных нам полей, а, также, налету, создать поле, в котором лежит
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,44012431Open in Telegram
  • C# Heppard

    25 Jun 2025, 19:38edited

    HasFlag #скоростьНедавно, как продвинутый, беседовал с Claude 4.0 Sonnet, который утверждал, что прямая битовая проверка (bitwise) наличия флага в enum быстрее, чем применение my_enum.HasFlag(flag). Я не поверил, так как проверял это пару лет назад, где-то в предоливьешные времена, после выхода .NET 5.Напомню, что enum может хранить как бы несколько значений, и может рассматриваться как битовое поле, то есть набор флагов. Например, тип оператора и его значение. Делается это просто, с помощью атрибута FlagsAttribute (пройдите по ссылке, там много полезной информации по использованию флагов в enum).[Flags] public enum Operator: short { None = 0x0,// Flags NonOperator = 0x0001, Comparison = 0x0002, ...// Comparison Operators Equals = 0x0700 | Comparison, NotEquals = 0x0800 | Comparison, ...
    Image from a post by C# HeppardImage from a post by C# Heppard
    1,960168Open in Telegram
  • C# Heppard

    9 Jun 2025, 07:43

    287321Open in Telegram
  • C# Heppard

    4 Jun 2025, 09:45edited

    IList as Span #скорость #памятьВ соседнем канале снова подняли вопрос по поводу разницы в скорости итерации по List<T> и IList<T>. Напомню, что я уже писал про это, но давно.Если кратко, то при итерации по IList возникает проблема с боксингом получаемого List<T>.Enumerator, так как он кастится к IEnumerator<T>. Это даёт 40 лишних байт аллокации. Также, вызов методов IEnumerator<T> приводит к поиску конкретной реализации по таблице виртуальных методов (callvirt в IL). Что, как не трудно догадаться, медленно, если существует более чем одна (это важно!) имплементация IEnumerator<T>.С тех пор, когда я про это писал, прошло много времени. Теперь я использую другой подход для случаев, когда коллеги используют IList, а мне ну уж очень надо выпендриться бежать по нему быстро.Этот метод есть в BCL, но является internal. Он весьма неплохо оптимизирован и используется, например, для
    Image from a post by C# HeppardImage from a post by C# Heppard
    3,3502410211Open in Telegram
  • C# Heppard

    23 May 2025, 17:31edited

    Быстрый код #отдых #философияОснователь компании id Software, гениальный и легендарный программист Джон Кармак признался, что вся современная индустрия компьютеров существует едва ли не благодаря не очень добросовестным программистам.В своем микроблоге в заблокированной в России американской соцсети Х (ранее Twitter) он написал, что миллиарды людей запросто могли бы работать на старых компьютерах и не тратить деньги на новые, если бы разработчики ставили в приоритет оптимизацию своего программного кода.Кармак открыто написал в своем микроблоге, что очень многие пользователи могли бы не тратить деньги на регулярное обновление ПК или покупку нового ноутбука."Большое количество пользователей по всему миру, чем многие могут себе представить, могли бы пользоваться устаревшим оборудованием, если бы оптимизация ПО на самом деле была приоритетом", – заявил создатель Doom.P.S.: Это
    3,1302566Open in Telegram
  • C# Heppard

    4 May 2025, 10:08edited

    StorageS3 0.6.4 #решение #хранилищеНа прошлой неделе выпустил новую версию библиотеки для экономного доступа к S3. Новая версия включает просьбы коллег по пробросу в библиотеку кастомного пула для массивов. Это было необходимо для случаев, когда стандартное поведение ArrayPool не устраивало.Также, добавлены исправления от других коллег, за что им большое спасибо!По традиции, обновил бенчмарки. Как оказалось, AWS (4.0.0) значительно улучшил производительность и потребление памяти. Minio тоже не стоит на месте, но всё ещё является не самой лучшей библиотекой для оптимального доступа к S3. Предыдущие замеры можно посмотреть тут.Новая версия уже в nuget.
    Image from a post by C# HeppardImage from a post by C# Heppard
    3,490292Open in Telegram
  • C# Heppard

    3 May 2025, 07:53

    forwarded from @ai_driven

    А теперь, для любителей локальных моделей: Gemma 3 QATЧто-то мы все про проприетарщину да и проприетарщину. А что насчет локальных моделей? Надо сказать, что на этом поприще у маленькмх опенсорных моделей тоже наблюдается какой-то фантастический буст. Например, Gemma 3 27B в кодинге показывает результаты, сопоставимые с GPT-4o-mini. А из ризонинг моделей, как упоминал ранее, QwQ 32B на уровне Claude 3.7 Sonnet Thinking, а DeepCoder 14B (это новая спец. моделька от создателей DeepSeek) на уровне o3-mini (low). Ну, и опять эксклюзив - на агентских задачах по кодингу, неожиданно вырвалась вперед моделька OpenHands LM 32B от ребят из OpenHands, которые дотренировали ее из Qwen Coder 2.5 Instruct 32B на своем "тренажере для агентов" SWE-Gym, опередив в итоге в SWE-bench даже огромную Deepseek V3 0324. В общем, OpenHands молодцы! Кстати, недавно их Code-агент взял новую соту (SoTA - State
    Image from a post by C# HeppardImage from a post by C# HeppardImage from a post by C# HeppardImage from a post by C# Heppard
    2,940136Open in Telegram
  • C# Heppard

    3 Apr 2025, 08:13edited

    Случайная строка из 12 символов #отдыхНедавно я снова упражнялся с роботами (LLM, GPT). Мне сказали, что они стали значительно умнее за последние 6 месяцев. Действительно, беседы на темы, где я не специалист выглядели весьма убедительно. Роботы стали предлагать более умные решения, исправляться и уточнять, если меня что-то не устраивает, признавать ошибки и предлагать альтернативные варианты.При этом, конечно, в областях, где я специалист, всё по прежнему не очень радужно. Так, простая задача по созданию случайной строки (random string) всё ещё решается в стиле "посмотреть на stackoverflow и предложить самый популярный вариант". Роботы прямо предлагали решения из вот этой вот темы.const string chars = "чарики"; return new string(Enumerable .Repeat(chars, length) .Select(s => s[random.Next(s.Length)]) .ToArray());Это решение мягко говоря сомнительное и не оптимальное (см. Linq в
    Image from a post by C# HeppardImage from a post by C# Heppard
    2,78015443Open in Telegram