11
votes

Générateur aléatoire rapide

Comment puis-je établir un RNG rapide (générateur de nombres aléatoires) dans C # qui prend en charge le remplissage d'un tableau d'octets avec une maxvalue (et / ou une mintaille)? J'ai trouvé ce http://www.codeproject.com/kb/cs/fastrandom.aspx mais n'a pas ces fonctions.


3 commentaires

Est le système.random trop lent?


C'est très bien peut être. Il remplit ses octets, ce qui est un cas assez spécial. Le code visant à remplir les octets pourrait probablement être un ordre de grandeur plus rapide ou plus. Est-ce qu'il a besoin cette vitesse? Je ne sais pas.


Oui, System.Random est trop lent. J'ai beaucoup de nombreux nombres aléatoires à générer.


5 Réponses :


-4
votes

Vous pouvez utiliser réflecteur pour décompiler System.Random à C #. Cela vous donnerait le code C # d'un générateur de nombres aléatoires rapide qui remplit vos besoins.


6 commentaires

En fait, non ... Le cadre est précompilé et optimisé, vous ne pouvez pas concurrencer cela (jusqu'à ce que vous ayez aussi précompiler votre code). Au moins, c'est l'expérience que j'ai faite (tout en essayant de dépasser le cadre;)).


Et pourquoi le ferait-il exactement? Vraisemblablement, depuis qu'il demande, aléatoire est trop lent, sinon il utiliserait ça, non?


@Bobby: déprimant, vrai. Le code propre précompilation ne vous aidera pas, cependant.


Et tout ce que je voulais, c'était à utiliser System.Random (directement). Je suppose que je devrais savoir mieux que ce que les gens détectent le sarcasme sur Internet ... =)


@Freed, oh ... Je pense que la réponse a semblé vraiment de sérieusement, et si vous avez eu la nuance de ", puis vous pouvez le modifier afin qu'il soit plus rapide" avec elle.


System.Random n'est pas un grand rng mais un objectif général (et simple) rng. Il n'y a rien à réutiliser de cela.



13
votes

System.Random est assez rapide pour n'importe quelle utilisation typique. Si vous rencontrez des problèmes de performance avec le code contenant des appels System.Random, assurez-vous de profiler votre code avant essayer de construire un nouveau aléatoire. Les chances sont vos problèmes de performance ne figurent pas dans le cadre, mais plutôt dans votre propre code.

Si vous appelez au hasard dans une boucle, assurez-vous de ne pas créer de nouvelle instance aléatoire avec chaque itération, mais vous utilisez plutôt une instance aléatoire commune. Faire cela améliorera les performances car vous ne créez pas de nouveaux objets pour le GC pour nettoyer et améliorera également la qualité des nombres aléatoires générés.


4 commentaires

Mon code n'a que de générer de nombreux nombres aléatoires en quelques secondes


C'est incroyable Combien de réponses décident de discuter des besoins de l'Asker au lieu de répondre à la question.


@Tazzo: Combien y a-t-il beaucoup? Quelles sont les exigences spécifiques que vous avez après? @Nosredna: répondant parfois à la question et aidant que l'Asker est deux choses différentes. Et qui se disputent?


Répondre à la question répond également aux personnes à l'avenir qui ont réellement besoin plus rapide .



-1
votes

Utilisez les services cryptographiques ....

RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
byte[] bytes= new byte[5];
crypto.GetBytes(bytes);


2 commentaires

Je ne l'ai pas chronométré moi-même, mais je devinerais que le RngCryptoServiceProvider, ayant la propriété supplémentaire d'être cryptographiquement en sécurité, serait plus lent que System.Random.


J'ai vérifié RngCryptoServiceProvider mais ne correspond pas à mes besoins, c'est ralentir et ne pas laisser un maximum de nombres aléatoires générés.



27
votes

Le fait que vous remplissez d'octets avec des entiers est suffisamment différent de l'étui d'utilisation typique de System.Random que vous pouvez probablement le battre mal si vous avez vraiment besoin.

System.Random est fait pour une utilisation générale. (En fait, je trouve habituellement des routines aléatoires système sans inspiration lorsque je fais des tests de vitesse et de distribution sur eux.) Il y a des cas où vous voudriez autre chose. Mais vous devez être très explicite sur vos besoins. À quelle vitesse? Que êtes-vous prêt à abandonner?

Si vous avez vraiment besoin de "rapide," Marsaglia a produit un nombre de nombres aléatoires très rapides générateurs pouvant être adaptés à vos besoins. Voici quelques liens sur l'un d'entre eux, Xorshift:


4 commentaires

Ce dernier lien était assez intéressant à examiner, +1


Merci pour votre réponse, le RNG doit être le plus rapide possible, j'ai de nombreux nombres aléatoires à générer en quelques secondes (10 ^ 9 et plus). J'ai essayé d'adapter la routine dans mon lien mais je n'ai pas coulé, pouvez-vous m'aider?


Il y a beaucoup de possibilités. Imaginez que vous avez configuré un tampon 4K de nombres aléatoires pour une plage (disons, 0-100). Utilisez un générateur de nombres aléatoires pour choisir un décalage et une prise, disons 16 octets de votre liste. Générez ensuite un autre offset et prenez des 16 autres octets. Ce ne sera pas fantastiquement aléatoire, mais cela peut être suffisamment aléatoire. Malgré mes demandes, vous ne m'avez pas dit ce que vous êtes prêt à abandonner pour obtenir la vitesse. Que ferez-vous avec tous ces chiffres?


Les chiffres sont pour un test et ne doivent pas être aléatoires à 100%



0
votes

Si vous avez un générateur de nombres aléatoires qui renvoie des numéros de l'intervalle de l'unité, comme celui de l'article du projet de code que vous avez mentionné, vous pouvez d'abord générer une valeur u à l'aide de ce générateur, puis de retourner A + (BA) * U Pour obtenir des valeurs entre A et B.


2 commentaires

Votre formule est incorrecte, si je choisis A = 5 et B = 20 et U = 55, j'ai 5 ans et plus (20-5) * 55 = 830. La formule droite est U / (UMAX + 1) * (B-A) + A lorsque UMAX est la valeur maximale du nombre aléatoire.


Si la valeur aléatoire U provient de l'intervalle d'unité , c'est-à-dire entre 0 et 1, la formule est correcte. Dans votre exemple, U = 55 n'est pas un nombre compris entre 0 et 1.