Информация об изменениях

Сообщение Re[15]: .net core и async lock от 11.04.2021 13:19

Изменено 12.04.2021 8:55 artelk

Re[15]: .net core и async lock
Здравствуйте, vdimas, Вы писали:

V>На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.

Хотелось бы посмотреть.

V>Заодно покажет, как тяжеловесные Task-и можно подменять обычными колбэками (делегатами), которые и так уже подаются state-машинкой в awaiter в готовом виде, т.е. доп. накладных расходов можно избежать практически полностью.

https://github.com/microsoft/referencesource/blob/master/mscorlib/system/threading/Tasks/Task.cs#L146
А чем таски тежеловесны? Слишком много полей? Методы слишком много делают?

Полагаю, ты завернешь колбак в тип, реализующий IValueTaskSource. Далее завернешь этот тип в ValueTask. Конструктор ValueTask принимает интерфейс, т.е. твой тип, даже если это была структура, будет жить в куче.
Какую-то очередь тебе в любом случае нужно будет делать. SemaphoreSlim работает как FIFO (правда, это свойство не отраженов документации, но лучше бы его воспроизвести). Это будет либо очередь на связном списке, либо что-то с массивами. Если есть основания считать, что твоя очередь лучше — можешь пул реквест сделать. Это деталь реализации SemaphoreSlim, спрятанная от клиентов. Есть большой шанс, что примут.

Еще вариант придумался: попробовать сделать свой собственный хитрый MyValueTask, не требующий боксинга. Очередь будет реализована через связный список массивов (примерно как реализован ConcurrentQueue), в которых по значению будут лежать нужные структуры. MyValueTask будет хранить ссылку на внутренний массив и индекс в нем. Свойство IsCompleted, в частности, будет смотреть в элемент этого массива и возвращать значение оттуда. В теории, должно получится Правда, "отработанные" массивы deque будут забираться GC только если все инстансы MyValueTask, на них ссылающиеся, удалятся. И от объектов в куче мы не избавились — мы массивы создаем. Переиспользование по кругу массивов (в которых все Task-и completed) не вариант, т.к. мы не знаем, живет ли еще хоть один MyValueTask, ссылающийся на наш массив. Не знаю, будет ли все это заметно эффективней, чем то, как сейчас SemaphoreSlim сделан.
Re[15]: .net core и async lock
Здравствуйте, vdimas, Вы писали:

V>На досуге нарисую легковесную реализацию и выложу сюда, т.к. судя по активности коллег оно может быть народу полезно.

Хотелось бы посмотреть.

V>Заодно покажет, как тяжеловесные Task-и можно подменять обычными колбэками (делегатами), которые и так уже подаются state-машинкой в awaiter в готовом виде, т.е. доп. накладных расходов можно избежать практически полностью.

https://github.com/microsoft/referencesource/blob/master/mscorlib/system/threading/Tasks/Task.cs#L146
А чем таски тежеловесны? Слишком много полей? Методы слишком много делают?

Полагаю, ты завернешь колбак в тип, реализующий IValueTaskSource. Далее завернешь этот тип в ValueTask. Конструктор ValueTask принимает интерфейс, т.е. твой тип, даже если это была структура, будет жить в куче.
Какую-то очередь тебе в любом случае нужно будет делать. SemaphoreSlim работает как FIFO (правда, это свойство не отраженов документации, но лучше бы его воспроизвести). Это будет либо очередь на связном списке, либо что-то с массивами. Если есть основания считать, что твоя очередь лучше — можешь пул реквест сделать. Это деталь реализации SemaphoreSlim, спрятанная от клиентов. Есть большой шанс, что примут.

Еще вариант придумался: попробовать сделать свой собственный хитрый MyValueTask, не требующий боксинга. Очередь будет реализована через связный список массивов (примерно как реализован ConcurrentQueue), в которых по значению будут лежать нужные структуры. MyValueTask будет хранить ссылку на внутренний массив и индекс в нем. Свойство IsCompleted, в частности, будет смотреть в элемент этого массива и возвращать значение оттуда. В теории, должно получится Правда, "отработанные" массивы будут забираться GC только если все инстансы MyValueTask, на них ссылающиеся, удалятся. И от объектов в куче мы не избавились — мы массивы создаем. Переиспользование по кругу массивов (в которых все Task-и completed) не вариант, т.к. мы не знаем, живет ли еще хоть один MyValueTask, ссылающийся на наш массив. Не знаю, будет ли все это заметно эффективней, чем то, как сейчас SemaphoreSlim сделан.