Is there an advantage of using Random() over Random.secure() if a cryptographically strong random number isn't required?

Viewed 144

Dart has two different ways of generating random numbers. Random() and Random.secure(), where the former is pseudo random. With only this information, it seems obvious that Random.secure() should be used all the time to be sure that the number generated is completely random.

However, since both ways of generating a number exists, I suspect that there are advantages of using Random(). Is that correct, and what are those advantages in that case?

1 Answers

I did some tests, and, like people commented, Random() is indeed faster.

When generating 100000 random integers between 0 and 100, Random() is 334 ms faster, and the average time to get one random number was 0.03 ms compared to 3.37 ms for Random.secure(). So unless you are generating a lot of numbers or the task you are doing requires a high speed, that difference probably won't matter.

Another difference I found comes from the documentation:

/// If the program cannot provide a cryptographically secure
/// source of random numbers, it throws an [UnsupportedError].

This means that Random.secure() might fail on some platforms, while Random() does not. So unless a secure number is required, Random() is probably preferred, since you don't have to care about error handling.

Here is the code I wrote to test the speed. There is probably some overhead from the for loops, but since I'm doing a comparison, that does not affect the difference.

import 'dart:math';

void main(List<String> arguments) {
  var psuedoRandom = Random();
  var secureRandom = Random.secure();

  var length = 100000;

  var startTime = DateTime.now();
  for (var i = 0; i < length; i++) {
    psuedoRandom.nextInt(100);
  }
  var psuedoDuration = DateTime.now().microsecondsSinceEpoch - startTime.microsecondsSinceEpoch;
  var psuedoAverage = psuedoDuration / length;

  startTime = DateTime.now();
  for (var i = 0; i < length; i++) {
    secureRandom.nextInt(100);
  }
  var secureDuration = DateTime.now().microsecondsSinceEpoch - startTime.microsecondsSinceEpoch;
  var secureAverage = secureDuration / length;

  var psuedoAdvantage = secureDuration - psuedoDuration;

  print('length: $length\n');

  print('psuedo duration: $psuedoDuration');
  print('psuedo average duration: $psuedoAverage\n');

  print('secure duration: $secureDuration');
  print('secure average duration: $secureAverage\n');

  print('Advantage for psuedo: $psuedoAdvantage');
}

Related