Проблема в том. Класс статический и использует вызов DateTime.Now. Если бы я сделал класс нестатическим и использовал структуру TimeProvider, все было бы хорошо и тестируемо, но... прежде чем начать, вот в чем загвоздка
- Класс будет вызываться 1000 раз в секунду. Производственная машина на данный момент является рекордсменом: 151964235 вызовов в секунду за 2 минуты. Статика была выбрана, чтобы не нагружать сборщик мусора.
- Каждое предлагаемое решение должно быть по крайней мере таким же быстрым, как и текущая реализация. Сюда входит фактическое время выполнения решения, время создания объекта и нагрузка на GC.
- Решения должны быть переносимыми и способными работать как на Windows, Linux, так и на Mac.
- Решения должны быть переносимыми и способными работать как на Windows, Linux, так и на Mac.
- li>
Другие идеи, как сделать это еще быстрее, конечно, очень приветствуются. - Основное беспокойство вызывает DateTime.Now. О UniqueId и Environment.CurrentManagedThreadId я подумаю позже.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Security.Cryptography;
///
/// generates instances of that are in ascending order.
///
///
/// It is both unique and ordered.
///
public static class SequentialGuid
{
private const long Rfc4122TicksBase = 499163040000000000; //1582-10-15 00:00:00
private const long SequentialGuidVersion = 0x6000;
private const int Variant = 0xC000;
private const int VariantMask = 0xC000;
private const long VersionMask = ~0x0FFFL;
private static readonly MapperAb EmptyMapperAb = new();
private static readonly MapperC EmptyMapperC;
private static readonly int Randomizer;
private static long _lastTicks;
private static int _sequence;
private static SpinLock _spinLock;
static SequentialGuid()
{
_spinLock = new SpinLock(false);
Randomizer = RandomNumberGenerator.GetInt32(int.MaxValue);
int rnd = RandomNumberGenerator.GetInt32(int.MaxValue);
rnd ^= Environment.ProcessId;
EmptyMapperC.UniqueId = (ushort)((rnd & 0xFFFF) ^ (rnd >> 16));
}
public static Guid NewGuid()
{
var mapperAb = EmptyMapperAb;
var mapperC = EmptyMapperC;
mapperAb.Ticks = GetTicksAndSequence(out mapperC.Sequence);
long ht = mapperAb.Ticks & ~VersionMask;
mapperAb.Ticks &= VersionMask;
mapperAb.Ticks
Подробнее здесь: https://stackoverflow.com/questions/790 ... -it-slower
Мобильная версия