Как заставить этот статический класс подчиняться TDD, не замедляя его работуC#

Место общения программистов C#
Ответить
Anonymous
 Как заставить этот статический класс подчиняться TDD, не замедляя его работу

Сообщение Anonymous »

Обновление: я изучил UUID v7 в .net9, упомянутый @Fildor. Однако UUID v7 делает почти то же самое, что и я, но значительно медленнее, чем моя реализация.
Обновление: я взглянул на реализацию EF Core 8, упомянутую @PanagiotisKanavos. В этой реализации используется не компонент реального времени, а время инициализации объекта в качестве основы для всех других созданных идентификаторов. Это может быть проблематично в сценарии, когда процессы, использующие этот класс, будут остановлены и запущены снова. Кроме того, нет ничего другого, что могло бы гарантировать уникальность.
Я хочу протестировать класс с помощью модульных тестов, чтобы убедиться, что он будет работать правильно в любых обстоятельствах. Класс должен генерировать уникальные результаты независимо от того, где (физическая машина, виртуальная машина, контейнер и т. д.) выполняется класс. Он даже должен генерировать уникальные результаты, если его запускать несколько раз параллельно в одной и той же среде.
Проблема в том. Класс является статическим и использует вызов DateTime.Now. Если бы я сделал класс нестатическим и использовал структуру TimeProvider, все было бы хорошо и тестируемо, но... прежде чем начать, вот в чем загвоздка
  • Класс будет вызываться 1000 раз в секунду. Производственная машина на данный момент является рекордсменом: 151964235 вызовов в секунду за 2 минуты. Статика была выбрана, чтобы не нагружать сборщик мусора.
  • Каждое предлагаемое решение должно быть по крайней мере таким же быстрым, как и текущая реализация. Сюда входит фактическое время выполнения решения, время создания объекта и нагрузка на GC.
  • Решения должны быть переносимыми и способными работать как на Windows, Linux, так и на Mac.
  • Решения должны быть переносимыми и способными работать как на Windows, Linux, так и на Mac.
  • li>
    Другие идеи, как сделать это еще быстрее, конечно, очень приветствуются.
  • Основное беспокойство вызывает DateTime.Now. О UniqueId и Environment.CurrentManagedThreadId я подумаю позже.

Код: Выделить всё

namespace HighPerformance.Utils;

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  Guid.NewGuid(); // UUIDv4

[Benchmark(Baseline = true)]
public Guid BenchmarkUuidV7() => Guid.CreateVersion7(); // UUIDv7

[Benchmark]
public Guid BenchmarkUuidV7Custom() => SequentialGuid.CreateVersion7(); // UUIDv7
}
 

Подробнее здесь: [url]https://stackoverflow.com/questions/79018722/how-to-make-this-static-class-obey-to-tdd-without-making-it-slower[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»