Skip to content

Commit b77c759

Browse files
author
MPCoreDeveloper
committed
Objects to generics fix and optimalization
1 parent 6349b40 commit b77c759

File tree

9 files changed

+1626
-30
lines changed

9 files changed

+1626
-30
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
// <copyright file="ModernizationBenchmark.cs" company="MPCoreDeveloper">
2+
// Copyright (c) 2024-2025 MPCoreDeveloper and GitHub Copilot. All rights reserved.
3+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
4+
// </copyright>
5+
using BenchmarkDotNet.Attributes;
6+
using BenchmarkDotNet.Order;
7+
using SharpCoreDB.DataStructures;
8+
using System.Diagnostics;
9+
10+
namespace SharpCoreDB.Benchmarks;
11+
12+
/// <summary>
13+
/// Benchmarks comparing OLD (Dictionary-based) vs NEW (Generic type-safe) implementations.
14+
/// Measures the impact of our C# 14 modernization with generics.
15+
/// </summary>
16+
[MemoryDiagnoser]
17+
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
18+
[RankColumn]
19+
public class ModernizationBenchmark
20+
{
21+
private const int RecordCount = 10_000;
22+
private GenericHashIndex<int>? _genericIndex;
23+
private Dictionary<int, List<long>>? _oldStyleIndex;
24+
private Random? _random;
25+
26+
[GlobalSetup]
27+
public void Setup()
28+
{
29+
Console.WriteLine("=== C# 14 Modernization Benchmark ===");
30+
Console.WriteLine($"Testing with {RecordCount:N0} records");
31+
Console.WriteLine();
32+
33+
_random = new Random(42);
34+
35+
// Setup NEW generic index
36+
_genericIndex = new GenericHashIndex<int>("test_column");
37+
for (int i = 0; i < RecordCount; i++)
38+
{
39+
_genericIndex.Add(i, i * 100);
40+
}
41+
42+
// Setup OLD dictionary-based index
43+
_oldStyleIndex = new Dictionary<int, List<long>>(RecordCount);
44+
for (int i = 0; i < RecordCount; i++)
45+
{
46+
if (!_oldStyleIndex.TryGetValue(i, out var positions))
47+
{
48+
positions = new List<long>();
49+
_oldStyleIndex[i] = positions;
50+
}
51+
positions.Add(i * 100);
52+
}
53+
54+
Console.WriteLine("? Setup completed - Ready to benchmark!");
55+
}
56+
57+
#region Lookup Benchmarks
58+
59+
[Benchmark(Baseline = true, Description = "OLD: Dictionary Lookup")]
60+
public long OldDictionaryLookup()
61+
{
62+
long sum = 0;
63+
for (int i = 0; i < 1000; i++)
64+
{
65+
var key = _random!.Next(RecordCount);
66+
if (_oldStyleIndex!.TryGetValue(key, out var positions))
67+
{
68+
sum += positions[0];
69+
}
70+
}
71+
return sum;
72+
}
73+
74+
[Benchmark(Description = "NEW: Generic Type-Safe Lookup")]
75+
public long NewGenericLookup()
76+
{
77+
long sum = 0;
78+
for (int i = 0; i < 1000; i++)
79+
{
80+
var key = _random!.Next(RecordCount);
81+
var positions = _genericIndex!.Find(key);
82+
sum += positions.FirstOrDefault();
83+
}
84+
return sum;
85+
}
86+
87+
#endregion
88+
89+
#region Insert Benchmarks
90+
91+
[Benchmark(Description = "OLD: Dictionary Insert (1000 records)")]
92+
public void OldDictionaryInsert()
93+
{
94+
var dict = new Dictionary<int, List<long>>();
95+
for (int i = 0; i < 1000; i++)
96+
{
97+
if (!dict.TryGetValue(i, out var positions))
98+
{
99+
positions = new List<long>(); // ALLOCATES!
100+
dict[i] = positions;
101+
}
102+
positions.Add(i);
103+
}
104+
}
105+
106+
[Benchmark(Description = "NEW: Generic Insert (1000 records)")]
107+
public void NewGenericInsert()
108+
{
109+
var index = new GenericHashIndex<int>("test");
110+
for (int i = 0; i < 1000; i++)
111+
{
112+
index.Add(i, i); // Optimized with pre-sized Dictionary
113+
}
114+
}
115+
116+
#endregion
117+
118+
#region Memory Efficiency
119+
120+
[Benchmark(Description = "OLD: Memory Usage (10k records)")]
121+
public Dictionary<int, List<long>> OldMemoryUsage()
122+
{
123+
var dict = new Dictionary<int, List<long>>();
124+
for (int i = 0; i < RecordCount; i++)
125+
{
126+
var list = new List<long> { i };
127+
dict[i] = list;
128+
}
129+
return dict;
130+
}
131+
132+
[Benchmark(Description = "NEW: Memory Usage (10k records)")]
133+
public GenericHashIndex<int> NewMemoryUsage()
134+
{
135+
var index = new GenericHashIndex<int>("test");
136+
for (int i = 0; i < RecordCount; i++)
137+
{
138+
index.Add(i, i);
139+
}
140+
return index;
141+
}
142+
143+
#endregion
144+
145+
#region Statistics Overhead
146+
147+
[Benchmark(Description = "NEW: Get Index Statistics")]
148+
public void GetIndexStatistics()
149+
{
150+
var stats = _genericIndex!.GetStatistics();
151+
// Access properties to ensure not optimized away
152+
_ = stats.UniqueKeys;
153+
_ = stats.Selectivity;
154+
_ = stats.MemoryUsageBytes;
155+
}
156+
157+
#endregion
158+
159+
[GlobalCleanup]
160+
public void Cleanup()
161+
{
162+
Console.WriteLine();
163+
Console.WriteLine("=== Benchmark Complete ===");
164+
165+
if (_genericIndex != null)
166+
{
167+
var stats = _genericIndex.GetStatistics();
168+
Console.WriteLine($"Final Index Statistics:");
169+
Console.WriteLine($" Unique Keys: {stats.UniqueKeys:N0}");
170+
Console.WriteLine($" Total Entries: {stats.TotalEntries:N0}");
171+
Console.WriteLine($" Memory Usage: {stats.MemoryUsageBytes / 1024.0:F2} KB");
172+
Console.WriteLine($" Selectivity: {stats.Selectivity:F4}");
173+
}
174+
}
175+
}

SharpCoreDB.Benchmarks/Program.cs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,52 @@
22
// Copyright (c) 2024-2025 MPCoreDeveloper and GitHub Copilot. All rights reserved.
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
// </copyright>
5-
namespace SharpCoreDB.Benchmarks;
5+
using BenchmarkDotNet.Running;
6+
using SharpCoreDB.Benchmarks;
67

7-
/// <summary>
8-
/// Main entry point for SharpCoreDB benchmarks.
9-
/// </summary>
10-
public class Program
8+
Console.WriteLine("??????????????????????????????????????????????????????????????????????");
9+
Console.WriteLine("? SharpCoreDB Performance Benchmark Suite ?");
10+
Console.WriteLine("? C# 14 Modernization Edition ?");
11+
Console.WriteLine("??????????????????????????????????????????????????????????????????????");
12+
Console.WriteLine();
13+
14+
// Check if running quick test
15+
if (args.Length > 0 && args[0] == "--quick")
16+
{
17+
Console.WriteLine("Running QUICK performance comparison...");
18+
Console.WriteLine();
19+
QuickPerformanceComparison.Run();
20+
return;
21+
}
22+
23+
Console.WriteLine("Select benchmark mode:");
24+
Console.WriteLine(" 1. Quick Comparison (fast, no overhead)");
25+
Console.WriteLine(" 2. Full BenchmarkDotNet Suite");
26+
Console.WriteLine(" 3. Modernization Benchmark Only");
27+
Console.WriteLine();
28+
Console.Write("Enter choice (1-3): ");
29+
30+
var choice = Console.ReadLine();
31+
32+
switch (choice)
1133
{
12-
public static void Main(string[] args)
13-
{
14-
// Use the comprehensive Group Commit comparison runner
15-
GroupCommitComparisonRunner.Run(args);
16-
}
34+
case "1":
35+
QuickPerformanceComparison.Run();
36+
break;
37+
38+
case "2":
39+
Console.WriteLine();
40+
Console.WriteLine("Running FULL BenchmarkDotNet suite...");
41+
BenchmarkRunner.Run<ModernizationBenchmark>();
42+
break;
43+
44+
case "3":
45+
Console.WriteLine();
46+
BenchmarkRunner.Run<ModernizationBenchmark>();
47+
break;
48+
49+
default:
50+
Console.WriteLine("Invalid choice, running quick comparison...");
51+
QuickPerformanceComparison.Run();
52+
break;
1753
}

0 commit comments

Comments
 (0)