From 21ef48b81c16da70ce7b29ec068b41d764a7f90b Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Sat, 26 Nov 2022 18:12:57 +0100 Subject: [PATCH] Minor performance enhancements. --- AsyncKeyedLock/AsyncKeyedLock.csproj | 8 ++++---- AsyncKeyedLock/AsyncKeyedLockPool.cs | 5 ++++- AsyncKeyedLock/AsyncKeyedLockReleaser.cs | 2 +- AsyncKeyedLock/AsyncKeyedLocker.cs | 5 ++++- AsyncKeyedLock/AsyncKeyedLockerDictionary.cs | 3 +++ README.md | 2 +- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/AsyncKeyedLock/AsyncKeyedLock.csproj b/AsyncKeyedLock/AsyncKeyedLock.csproj index 2d4392b..e864bb7 100644 --- a/AsyncKeyedLock/AsyncKeyedLock.csproj +++ b/AsyncKeyedLock/AsyncKeyedLock.csproj @@ -7,16 +7,16 @@ https://github.com/MarkCiliaVincenti/AsyncKeyedLock.git https://github.com/MarkCiliaVincenti/AsyncKeyedLock LICENSE - 5.0.2-rc + 5.0.3 logo.png - Performance improvements and allowing for object pooling. + Minor performance enhancements. An asynchronous .NET Standard 2.0 library that allows you to lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number. © 2022 Mark Cilia Vincenti async,lock,key,semaphore,dictionary,pooling,duplicate git false - 5.0.1.9 - 5.0.1.9 + 5.0.3.0 + 5.0.3.0 README.md true true diff --git a/AsyncKeyedLock/AsyncKeyedLockPool.cs b/AsyncKeyedLock/AsyncKeyedLockPool.cs index 282d86e..486d003 100644 --- a/AsyncKeyedLock/AsyncKeyedLockPool.cs +++ b/AsyncKeyedLock/AsyncKeyedLockPool.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Runtime.CompilerServices; namespace AsyncKeyedLock { @@ -12,12 +13,13 @@ public AsyncKeyedLockPool(Func> objectGenerat { _objects = new BlockingCollection>(new ConcurrentBag>(), capacity); _objectGenerator = objectGenerator; - for (int i = 0; i < capacity; i++) + for (int i = 0; i < capacity; ++i) { _objects.Add(_objectGenerator(default)); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public AsyncKeyedLockReleaser GetObject(TKey key) { if (_objects.TryTake(out var item)) @@ -28,6 +30,7 @@ public AsyncKeyedLockReleaser GetObject(TKey key) return _objectGenerator(key); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PutObject(AsyncKeyedLockReleaser item) { _objects.TryAdd(item); diff --git a/AsyncKeyedLock/AsyncKeyedLockReleaser.cs b/AsyncKeyedLock/AsyncKeyedLockReleaser.cs index 364df0b..7bffde6 100644 --- a/AsyncKeyedLock/AsyncKeyedLockReleaser.cs +++ b/AsyncKeyedLock/AsyncKeyedLockReleaser.cs @@ -50,7 +50,7 @@ internal bool TryIncrement() { if (Monitor.TryEnter(this)) { - _referenceCount++; + ++_referenceCount; Monitor.Exit(this); return true; } diff --git a/AsyncKeyedLock/AsyncKeyedLocker.cs b/AsyncKeyedLock/AsyncKeyedLocker.cs index 4c0ed10..1b2fc77 100644 --- a/AsyncKeyedLock/AsyncKeyedLocker.cs +++ b/AsyncKeyedLock/AsyncKeyedLocker.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace AsyncKeyedLock { /// - /// AsyncKeyedLock class, originally inspired by Stephen Cleary's solution. + /// Represents a lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number. /// public sealed class AsyncKeyedLocker : AsyncKeyedLocker { @@ -196,7 +197,9 @@ public AsyncKeyedLocker(AsyncKeyedLockOptions options, int concurrencyLevel, int /// /// The key for which a releaser should be obtained. /// A created or retrieved . + [MethodImpl(MethodImplOptions.AggressiveInlining)] public AsyncKeyedLockReleaser GetOrAdd(TKey key) => _dictionary.GetOrAdd(key); + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Release(AsyncKeyedLockReleaser releaser) => _dictionary.Release(releaser); diff --git a/AsyncKeyedLock/AsyncKeyedLockerDictionary.cs b/AsyncKeyedLock/AsyncKeyedLockerDictionary.cs index e705fdd..71697ed 100644 --- a/AsyncKeyedLock/AsyncKeyedLockerDictionary.cs +++ b/AsyncKeyedLock/AsyncKeyedLockerDictionary.cs @@ -1,5 +1,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Threading; namespace AsyncKeyedLock @@ -66,6 +67,7 @@ public AsyncKeyedLockerDictionary(AsyncKeyedLockOptions options, int concurrency } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public AsyncKeyedLockReleaser GetOrAdd(TKey key) { if (TryGetValue(key, out var referenceCounter) && referenceCounter.TryIncrement()) @@ -110,6 +112,7 @@ public AsyncKeyedLockReleaser GetOrAdd(TKey key) return referenceCounter; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Release(AsyncKeyedLockReleaser referenceCounter) { Monitor.Enter(referenceCounter); diff --git a/README.md b/README.md index 1f8b92c..06b91f7 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,4 @@ bool isInUse = asyncKeyedLocker.IsInUse(myObject); ``` ## Credits -This library was originally inspired by [Stephen Cleary's solution](https://stackoverflow.com/questions/31138179/asynchronous-locking-based-on-a-key/31194647#31194647). +This library was originally inspired by [Stephen Cleary's solution](https://stackoverflow.com/questions/31138179/asynchronous-locking-based-on-a-key/31194647#31194647), but has gone through a lot of changes since. \ No newline at end of file