@GrigorySvetov

Криптонадежные числа в .NET быстрее System.Random()?

Пожалуйста, объясните, почему (как минимум в тестах на PascalABC.NET) код №1 работает быстрее ~ в 3 раза, чем код №2?
//№1
var
  arr: array of byte;
  rndg := new System.Security.Cryptography.RNGCryptoServiceProvider();

begin
  setlength(arr, 10000000);
  rndg.GetBytes(arr);
  write(milliseconds());//от 50 до 70
end.

//№2
var
  arr: array of byte;
  rnd := new System.Random();

begin
  setlength(arr, 10000000);
  rnd.NextBytes(arr);
  write(milliseconds);//от 160 до 200
end.


Почему генерация криптонадёжных (по документации .NET) случайных требует весомо меньших ресурсов времени, чем стандартных?

(при повышении длины массива до 100 млн элементов на криптослучайные тратится ~ 0,3 с, а на стандартные где-то 1,5 с)
(кстати: при тесте 1 млрд криптослучайных заметны весомые потери памяти, хотя всё оказалось вычислено за 41 с; при аналогичном тесте 1 млрд стандартно-случайных было потрачено 18 сек (ВНЕЗАПНО), а зависаний по тратам памяти особо не было (память не мерил, просто общее ощущение от самого "поведения" компа)).

Итого, меняю вопрос: просто прошу прокомментировать это поведение .NET'а (.NET'а ли???), по возможности объяснив его; в том числе интересен "излом" на 1 млрд байт.
  • Вопрос задан
  • 83 просмотра
Решения вопроса 2
profesor08
@profesor08
Полагаю, но это не точно, в первом случае, тебе возвращаются некие данные, которые уже где-то генерируются системой, и ты получаешь к ним доступ. Во втором ты генерируешь их на лету.

Переломный момент на мой взгляд очевиден, в какой-то момент становится слишком сложно, чтоб генерировать все на лету. В то время как второй случай продолжает генерировать с определенной скоростью.

А еще может просто маловато оперативки и данные улетают в файл подкачки со всеми его недостатками.
Ответ написан
Комментировать
yarosroman
@yarosroman
C# the best
Полагаю то, что генерация крипто вызывается из внешнего оптимизированного небезопасного кода. а у обычного, возникает, скорее всего, много накладных расходов по работе (GC, проверка границ массивов). ну и замерять научитесь, у меня такие данные после теста

BenchmarkDotNet=v0.10.14, OS=Windows 10.0.16299.547 (1709/FallCreatorsUpdate/Redstone3)
Intel Core i7-4770K CPU 3.50GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
Frequency=3423912 Hz, Resolution=292.0636 ns, Timer=TSC
[Host] : .NET Framework 4.6.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3130.0
DefaultJob : .NET Framework 4.6.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3130.0

Method | I | Mean | Error | StdDev | Rank |
------- |---------- |---------------:|--------------:|--------------:|-----:|
Cripto | 10000 | 5.620 us | 0.0032 us | 0.0029 us | 1 |
Simple | 10000 | 84.398 us | 0.0452 us | 0.0401 us | 2 |
Cripto | 100000000 | 94,948.080 us | 1,126.6868 us | 1,053.9034 us | 3 |
Simple | 100000000 | 854,149.505 us | 2,348.7335 us | 2,197.0066 us | 4 |

// * Hints *
Outliers
CryptoVsSimpleRandom.Simple: Default -> 1 outlier was removed

// * Legends *
I : Value of the 'I' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Rank : Relative position of current benchmark mean among all benchmarks (Arabic style)
1 us : 1 Microsecond (0.000001 sec)

использовал BenchmarkDotNet
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы