Найти тему
StorageS3 0.6.2
Удивительно, но библиотека соединения с Minio жива и даже используется некоторыми коллегами. И, что особенно удивительно, коллеги проявляют интерес к тому, чтобы помогать эту библиотеку разрабатывать. Каюсь, первый и единственный PR висел почти год. Уважаемый коллега, который его сделал, прости меня! Короче говоря, смерджил изменения, добавил пару правок от себя и теперь библиотекой снова можно пользоваться - она в nuget...
10 месяцев назад
C# string Array.IndexOf
В комментариях заметили интересное поведение при поиске строки в массиве. Если сделать Array.IndexOf по массиву строк, то скорость получается несколько ниже простого перебора в foreach со сравнением через Equals. Было предположение, что проблема в EqualityComparer<string>.Default (который, на самом деле GenericEqualityComparer<string>), но и это оказалось не верным предположением. То есть проблема где-то в Array.IndexOf. Оказалось верным подтвержденное бенчмарком предложение,...
10 месяцев назад
C# Tree<T>
Дерево - очень полезная структура данных. Помимо того, что про него спрашивают на собеседованиях, дерево помогает хранить иерархически упорядоченные данные. Например, дерево элементов HTML, дерево зависимостей сущностей в игре, дерево подразделений в компании. Имплементация дерева лаконична и проста: public class Tree<T>(Tree<T>? parent, T value) { public readonly List<Tree<T>> Children = []; public readonly Tree<T>? Parent = parent; public readonly T Value = value; public Tree<T> Add(T value) { var child = new Tree<T>(this, value); Children...
10 месяцев назад
DateTime и StringBuilder
При работе со StringBuilder есть ещё одна неприятность: метод StringBuilder.Append прекрасен, но, по какой-то странной для меня причине, не имеет перегрузки для DateTime. Я знаю, что многие разработчики просто передают туда дату и... попадают на boxing, поскольку будет выбран метод с сигнатурой, принимающей object. Либо, что тоже странно, коллеги просто делают dateTime.ToString(), аллоцируя промежуточную строку и просто передавая её в StringBuilder.Append. Вроде бы ничего страшного, вроде бы очень очень маленькая аллокация...
10 месяцев назад
String на stack'е
Напоминаю про чудесный ValueStringBuilder, который находится в недрах .NET и является internal. Это идеальная вещь для замены StringBuilder на коротких строках. Фактически, он является одним из распространённых подходов к написанию zero-allocation кода. Чтобы его использовать в своём приложении необходимо... просто скопировать его код из репозитория .NET. Штука до боли простая - это ref struct, которая принимает в конструктор Span<char>. Обычно его создают на стеке путём stackallock char[256]. Если в процессе создания строки выяснятся, что переданного Span не хватает - используется честный массив из ArrayPool...
10 месяцев назад
Enumerator C#
Могие почему-то боятся делать перечислители (Enumerator) для своих коллекций, выставляя наружу внутренние массивы List или Dictionary. Чуть более смелые разработчики, желая сохранить инкапсуляцию, выставляют из сущностей IEnumerable или даже более правильный IReadOnlyCollection, делая свои коллекции приватными, но доступными через свойство. А вот если нам нужно что-то сделать перед передачей элемента коллекции из сущности, то добро пожаловать в LINQ: коллеги просто возвращают IEnumerable где начинают городить в возвращаемом свойстве что-то вроде _collection.Select(id => new Actor(conext, id)). Давайте не будем так делать...
10 месяцев назад
Мониторинг приложения в Rider
В Rider появился инструмент поверхностного мониторинга работающего приложения. Этот функционал IDE будет знаком пользователям Visual Studio. Мой канал в TG: https://t.me/csharp_gepard
10 месяцев назад
Garnet .NET
Я специально не писал про Garnet, хотя и признаю - это отличная тема про производительность. Однако, с моей точки зрения, это весьма сомнительная штуковина в плане имплементации (см. вот эту дискуссию). Да, скорость это круто. Да, оно работает. Да, я бы на него перешёл хотя бы из-за лицензии. Но я не понимаю коллег, которые его создали. Ну, чисто как разработчик. Ведь что мы имеем? Множество unsafe, свой собственный менеджер памяти для того, чтобы миновать GC. Поверх этого имеем кучу специальных подходов, которые могли быть заменены на подходы современного C#. Кстати, без изоленты и палок. Зачем это было? Мол, прикинь, братва, как много хаков можно написать в коде? Супер, спасибо...
10 месяцев назад
CollectionsMarshal
Ваши коллеги любят List<T>, а вы желаете окунуться в мир Span<T>? Выход есть! List<int> list = [1, 2, 3, 4, 5]; var span = CollectionsMarshal.AsSpan(list); Ваши коллеги любят Dictionary<TKey, TValue>, а вы, в тайне от них, мечтаете пощупать механику работы с ref? Выход есть снова! var dic = new Dictionary<int, int> { { 1, 1 }, { 2, 2 } }; ref var value = ref CollectionsMarshal.GetValueRefOrNullRef(dic, 2); if (!Unsafe.IsNullRef(ref value)) value = 2222; Console.WriteLine(dic[2]); Вам надоело передавать структуры через Nullable<T> и вы мечтаете быть модным и шелковистым? Опять выход рядом! Обратите внимание на конструкцию Unsafe...
10 месяцев назад
Сколько платят специалистам в .NET
Коллеги, хочу сделать новую рубрику: актуальные данные по зарплатам. Это, кажется, сильно влияет на нашу производительность. Я сторонник открытых данных о зарплатах, так как это позволяет нам лучше и честнее разговаривать с работодателями о том, что мы хотим и куда мы движемся. Ну и, также, позволяет продавать наше время и умения более выгодно. Цифры без учёта бонусов и прочего, чистые деньги после налогов по зарплатам в месяц. И только по dotnet'у. Деньги в тысячах. Архитектор: 400-500. Тимлид: 350-400...
10 месяцев назад
Видео DotNext
Недавно опубликовали первое видео с последнего DotNext. Мне приятно, что первым опубликованным был некто Евгений, и про производительность. Почему доклад может быть интересен? Мой канал в TG: https://t.me/csharp_gepard
10 месяцев назад
InlineArrayAttribute
С момента появления InlineArrayAttribute (мотивация) я хотел на него посмотреть в деле. Напомню, что это атрибут для структур, который "размножает" поле, в котором лежит "элемент массива". Также, атрибут добавляет индексатор для доступа к значениям, чтобы структура стала похожей на массив. Значения через индексатор попадают в сгенерированные поля, откуда могут быть получены позже. И это всё на стеке, т.е. тот самый zero-allocation. [System.Runtime.CompilerServices.InlineArray(10)] public struct Buffer10 { private int _element0; } Единственная проблема: по поведению это массив, т...
10 месяцев назад