@AlenAfrikyan

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

В чем разница, и как правильно сделать: создать экземпляр или прямо вызвать?

Random random = new Random();
int r = random.Next(1, 10);

int r1 = new Random().Next(1, 10);
  • Вопрос задан
  • 158 просмотров
Решения вопроса 2
@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
Ответ написан
vabka
@vabka Куратор тега C#
Токсичный шарпист
Лучше по возможности переиспользовать 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
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы