Skip to content

Commit 682377b

Browse files
committed
Create benchmark for Core.RemoveObjectFromList() implementation
1 parent d952fff commit 682377b

File tree

7 files changed

+1188
-0
lines changed

7 files changed

+1188
-0
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Concurrent;
4+
using System.Linq;
5+
using NetOffice;
6+
7+
namespace NetOffice.Benchmarks
8+
{
9+
/// <summary>
10+
/// Base interface for Core collection variants to enable polymorphic benchmarking
11+
/// </summary>
12+
internal interface ICoreCollectionVariant
13+
{
14+
void AddObject(ICOMObject obj);
15+
bool RemoveObject(ICOMObject obj);
16+
void Clear();
17+
int Count { get; }
18+
}
19+
20+
/// <summary>
21+
/// Variant 1: Current implementation using List (baseline)
22+
/// Time: O(n) per removal
23+
/// Memory: O(n)
24+
/// </summary>
25+
internal class ListCoreVariant : ICoreCollectionVariant
26+
{
27+
private readonly List<ICOMObject> _globalObjectList = new List<ICOMObject>();
28+
private readonly object _lock = new object();
29+
30+
public void AddObject(ICOMObject obj)
31+
{
32+
lock (_lock)
33+
{
34+
_globalObjectList.Add(obj);
35+
}
36+
}
37+
38+
public bool RemoveObject(ICOMObject obj)
39+
{
40+
lock (_lock)
41+
{
42+
return _globalObjectList.Remove(obj);
43+
}
44+
}
45+
46+
public void Clear()
47+
{
48+
lock (_lock)
49+
{
50+
_globalObjectList.Clear();
51+
}
52+
}
53+
54+
public int Count
55+
{
56+
get
57+
{
58+
lock (_lock)
59+
{
60+
return _globalObjectList.Count;
61+
}
62+
}
63+
}
64+
}
65+
66+
/// <summary>
67+
/// Variant 2: HashSet implementation (proposed solution)
68+
/// Time: O(1) per removal (average)
69+
/// Memory: O(n) with higher constant factor
70+
/// Requires proper GetHashCode() and Equals() implementation
71+
/// </summary>
72+
internal class HashSetCoreVariant : ICoreCollectionVariant
73+
{
74+
private readonly HashSet<ICOMObject> _globalObjectList = new HashSet<ICOMObject>();
75+
private readonly object _lock = new object();
76+
77+
public void AddObject(ICOMObject obj)
78+
{
79+
lock (_lock)
80+
{
81+
_globalObjectList.Add(obj);
82+
}
83+
}
84+
85+
public bool RemoveObject(ICOMObject obj)
86+
{
87+
lock (_lock)
88+
{
89+
return _globalObjectList.Remove(obj);
90+
}
91+
}
92+
93+
public void Clear()
94+
{
95+
lock (_lock)
96+
{
97+
_globalObjectList.Clear();
98+
}
99+
}
100+
101+
public int Count
102+
{
103+
get
104+
{
105+
lock (_lock)
106+
{
107+
return _globalObjectList.Count;
108+
}
109+
}
110+
}
111+
}
112+
113+
/// <summary>
114+
/// Variant 3: Dictionary keyed by IntPtr (alternative)
115+
/// Time: O(1) per removal by key
116+
/// Memory: O(n)
117+
/// Benefit: Can key by COM pointer for guaranteed uniqueness
118+
/// </summary>
119+
internal class DictionaryCoreVariant : ICoreCollectionVariant
120+
{
121+
private readonly Dictionary<int, ICOMObject> _globalObjectList = new Dictionary<int, ICOMObject>();
122+
private readonly object _lock = new object();
123+
124+
public void AddObject(ICOMObject obj)
125+
{
126+
lock (_lock)
127+
{
128+
int key = obj.GetHashCode();
129+
_globalObjectList[key] = obj;
130+
}
131+
}
132+
133+
public bool RemoveObject(ICOMObject obj)
134+
{
135+
lock (_lock)
136+
{
137+
int key = obj.GetHashCode();
138+
return _globalObjectList.Remove(key);
139+
}
140+
}
141+
142+
public void Clear()
143+
{
144+
lock (_lock)
145+
{
146+
_globalObjectList.Clear();
147+
}
148+
}
149+
150+
public int Count
151+
{
152+
get
153+
{
154+
lock (_lock)
155+
{
156+
return _globalObjectList.Count;
157+
}
158+
}
159+
}
160+
}
161+
162+
/// <summary>
163+
/// Variant 4: ConcurrentDictionary (lock-free alternative)
164+
/// Time: O(1) per removal (average)
165+
/// Memory: O(n) with higher overhead
166+
/// Benefit: Reduces lock contention with built-in thread-safety
167+
/// </summary>
168+
internal class ConcurrentDictionaryCoreVariant : ICoreCollectionVariant
169+
{
170+
private readonly ConcurrentDictionary<int, ICOMObject> _globalObjectList =
171+
new ConcurrentDictionary<int, ICOMObject>();
172+
173+
public void AddObject(ICOMObject obj)
174+
{
175+
int key = obj.GetHashCode();
176+
_globalObjectList[key] = obj;
177+
}
178+
179+
public bool RemoveObject(ICOMObject obj)
180+
{
181+
int key = obj.GetHashCode();
182+
return _globalObjectList.TryRemove(key, out _);
183+
}
184+
185+
public void Clear()
186+
{
187+
_globalObjectList.Clear();
188+
}
189+
190+
public int Count => _globalObjectList.Count;
191+
}
192+
}

0 commit comments

Comments
 (0)