Убрал два косяка предыдущей версии (на скорость не влияли) и ещё ускорил. Пробовал заменить TestClass на TestStruct, но тут это ничего не даёт, разве что чуть экономит память. Ещё воткнул GC.Collect между итерациями, т.к. надоело видеть первую итерацию самой быстрой.
| C# |
| using System;
using System.Diagnostics;
using System.Threading;
namespace QuickSort
{
public class Program
{
private static int activeThreadCount;
private static ManualResetEvent waitHandle = new ManualResetEvent(false);
public static void Main(string[] args)
{
const int ARRAY_SIZE = 1000 * 1000;
const int THREADS = 4;
var watch = new Stopwatch();
for (var i = 0; i < 5; i++)
{
GC.Collect();
watch.Restart();
waitHandle.Reset();
var vals = new TestClass[ARRAY_SIZE];
activeThreadCount = 4;
for (var j = 0; j < THREADS; j++)
{
int segmentIndex = j;
ThreadPool.QueueUserWorkItem(_ => Fill(vals, segmentIndex * (ARRAY_SIZE / THREADS), ARRAY_SIZE / THREADS));
}
waitHandle.WaitOne();
watch.Stop();
Console.WriteLine($"Total: {watch.ElapsedMilliseconds} ms");
}
Console.WriteLine($"GC: {GC.CollectionCount(0)} {GC.CollectionCount(1)} {GC.CollectionCount(2)}");
Console.ReadLine();
}
private static void Fill(TestClass[] array, int start, int count)
{
int end = start + count;
for (int i = start; i < end; i++)
{
array[i] = new TestClass();
}
Interlocked.Decrement(ref activeThreadCount);
if (activeThreadCount == 0)
{
waitHandle.Set();
}
}
}
internal class TestClass
{
public string Id = CreateGuid();
public string Value = CreateGuid();
private static ThreadLocal<Random> localRandom = new ThreadLocal<Random>(() => new Random());
public override string ToString() => Id;
private static unsafe string CreateGuid()
{
var num = localRandom.Value.Next(100_000_000);
var chars = stackalloc char[11]; // null-terminated 10-char string
chars[0] = '0';
chars[1] = '0';
chars[2] = (char)('0' + num % 10); num /= 10;
chars[3] = (char)('0' + num % 10); num /= 10;
chars[4] = (char)('0' + num % 10); num /= 10;
chars[5] = (char)('0' + num % 10); num /= 10;
chars[6] = (char)('0' + num % 10); num /= 10;
chars[7] = (char)('0' + num % 10); num /= 10;
chars[8] = (char)('0' + num % 10); num /= 10;
chars[9] = (char)('0' + num % 10);
return new string(chars);
}
}
}
|
| |
Total: 195 ms
Total: 177 ms
Total: 179 ms
Total: 169 ms
Total: 189 ms
GC: 113 46 13