• В чeм разница и как правильно сделать?

    Лучше по возможности переиспользовать Random, тк создание его экземпляра достаточно дорогое
    Но стоит учитывать следующие моменты:
    1. Он по умолчанию не является потокобезопасным, а это значит, что нельзя один экземпляр использовать в нескольких потоках. Это черевато дублированием случайных значений
    2. Random - генератор псевдослучайных чисел, а это значит, что его нельзя использовать для криптографии

    Ну и вот результаты замеров
    using BenchmarkDotNet.Attributes;
    using BenchmarkDotNet.Running;
    
    BenchmarkRunner
        .Run<RandomBenchmarks>();
    
    [MemoryDiagnoser]
    public class RandomBenchmarks
    {
        private static readonly Random Random = new();
    
        [Benchmark]
        public void Reuse()
        {
            Random.Next();
        }
    
        [Benchmark]
        public void CreateNew()
        {
            new Random().Next();
        }
    }


    // * Summary *
    
    BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22463
    AMD Ryzen 5 4600H with Radeon Graphics, 1 CPU, 12 logical and 6 physical cores
    .NET SDK=6.0.100-rc.1.21463.6
      [Host]     : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT
      DefaultJob : .NET 6.0.0 (6.0.21.45113), X64 RyuJIT
    
    
    |    Method |       Mean |     Error |    StdDev |  Gen 0 | Allocated |
    |---------- |-----------:|----------:|----------:|-------:|----------:|
    |     Reuse |   3.128 ns | 0.0987 ns | 0.1351 ns |      - |         - |
    | CreateNew | 114.934 ns | 2.3160 ns | 4.8852 ns | 0.0343 |      72 B |
    
    // * Legends *
      Mean      : Arithmetic mean of all measurements
      Error     : Half of 99.9% confidence interval
      StdDev    : Standard deviation of all measurements
      Gen 0     : GC Generation 0 collects per 1000 operations
      Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
      1 ns      : 1 Nanosecond (0.000000001 sec)

    Может показаться, что 72 байта на операцию - это не много, но это:
    1. Это 70мб на 1млн операций, против 72байт
    2. Это миллион лишних объектов в куче против одного, что добавляет лишней работы для GC
    Ответ написан
    2 комментария
  • В чeм разница и как правильно сделать?

    @spaceatmoon
    Для одиночного вызова разницы никакой. Однако по логике, вызов конструктора намного сильнее тормозит программу, нежели просто вызвать функцию Next.

    DateTime timeStart = DateTime.Now;
    for (int i = 0; i < 10000; i++)
    {
        int random = new Random().Next(1, 10);
    }
    DateTime timeStop = DateTime.Now;
    Console.WriteLine("new Random().Next(1, 10) - {0}", timeStop - timeStart);
    //
    timeStart = DateTime.Now;
    Random random1 = new Random();
    for (int i = 0; i < 10000; i++)
    {
        int dig = random1.Next(1, 10);
    }
    timeStop = DateTime.Now;
    Console.WriteLine("random.Next(1, 10) - {0}", timeStop - timeStart);

    new Random().Next(1, 10) - 00:00:00.0209561
    random.Next(1, 10) - 00:00:00.0001170
    Ответ написан
    2 комментария