RandomKit est un cadre rapide qui rend la génération de données aléatoires simple et facile.
| Bifurquer | Statut |
|---|---|
master |
RandomKit est peut-être également compatible avec FreeBSD, Android et Windows (sous Cygwin) mais n'a pas été testé pour ces plateformes.
Le Swift Package Manager est un gestionnaire de dépendances décentralisé pour Swift.
Ajoutez le projet à votre Package.swift .
import PackageDescription
let package = Package (
name : " MyAwesomeProject " ,
dependencies : [
. Package ( url : " https://github.com/nvzqz/RandomKit.git " ,
majorVersion : 5 )
]
)Importez le module RandomKit.
import RandomKitCocoapods est un gestionnaire de dépendances centralisé pour Objective-C et Swift. Allez ici pour en savoir plus.
Ajoutez le projet à votre podfile.
use_frameworks!
pod 'RandomKit' , '~> 5.2.3'Si vous voulez être sur le bord de saignement, remplacez la dernière ligne par:
pod 'RandomKit' , :git => 'https://github.com/nvzqz/RandomKit.git' Exécutez pod install et ouvrez le fichier .xcworkspace pour lancer Xcode.
Importez le cadre RandomKit.
import RandomKitCarthage est un gestionnaire de dépendances décentralisé pour Objective-C et Swift.
Ajoutez le projet à votre cartouche.
github "nvzqz/RandomKit"
Exécutez carthage update et suivez les étapes supplémentaires afin d'ajouter RandomKit à votre projet.
Importez le cadre RandomKit.
import RandomKit Diverses composantes de RandomKit peuvent être facilement comparées en exécutant benchmark.sh .
./benchmark.sh [FLAGS] [PROTOCOLS] Utilisez l'indicateur --help pour des informations sur la façon de l'utiliser.
Remarque: Le nombre par défaut est 10000000, ce qui est beaucoup si vous utilisez l'indicateur --array . Cela peut être modifié en passant un argument dans --count ou -c .
Essayez-le par vous-même! Téléchargez le dépôt et ouvrez «Randomkit.Playground».
Le protocole RandomGenerator définit les méthodes de base pour générer des valeurs primitives et randomiser un tampon.
Tous les types fournis conformes à RandomGenerator ont une valeur default statique qui peut être transmise comme un argument inout aux fonctions de génération.
let value = Int . random ( using : & Xoroshiro . default ) ARC4Random
arc4random ne sont pas exportés avec Foundation sur Linux et d'autres plates-formes, elles sont chargées dynamiquement au moment de l'exécution. DeviceRandom
MersenneTwister
Xoroshiro
Xorshift
XorshiftStar
ChaCha
SeedableRandomGenerator est destiné aux types qui peuvent être ensemencés avec un type Seed associé.
Le protocole RandomBytesGenerator concerne des types spécialisés dans la génération d'un type spécifique qui remplit un certain nombre d'octets. Par exemple, MersenneTwister est spécialisé dans la génération UInt64 tandis que Xorshift génère des valeurs UInt32 .
Pour les programmes unique, il est sûr d'utiliser une instance de générateur global tel que Xoroshiro.default comme source d'aléatoire.
Pour les programmes multi-thread, les instances de thread-locales doivent être utilisées. Cela permet à différents threads d'utiliser leurs propres générateurs aléatoires séparés sans état mutable partagé.
Dans l'exemple suivant, randomGenerator est unique à chaque fil.
let randomBytes = Xoroshiro . withThreadLocal { randomGenerator in
return [ UInt8 ] ( randomCount : 1000 , using : & randomGenerator )
}Les générateurs de filetage sont traités à la sortie du thread, il n'est donc pas nécessaire de s'inquiéter du nettoyage.
Il est recommandé de ne pas appeler withThreadLocal(_:) ou d'obtenir le pointeur threadLocal à chaque fois que cela est nécessaire. La récupération de l'instance de fil locale entraîne des frais généraux évitables.
// Bad
let value = Int . random ( using : & Xoroshiro . threadLocal . pointee )
array . shuffle ( using : & Xoroshiro . threadLocal . pointee )
// Good
let threadLocal = Xoroshiro . threadLocal
let value = Int . random ( using : & threadLocal . pointee )
array . shuffle ( using : & threadLocal . pointee )
// Better
Xoroshiro . withThreadLocal { randomGenerator in
let value = Int . random ( using : & randomGenerator )
array . shuffle ( using : & randomGenerator )
}En tant que raccourci, vous pouvez même appliquer une fonction directement comme paramètre.
let value = Xoroshiro . withThreadLocal ( Int . random ) Avant la v4.4.0, la sécurité des fils pourrait être obtenue en instanciant une nouvelle instance de semence d'un type de type RandomGenerator donné. Le problème avec cela est que l'ensemencement inutile se produit à chaque fois. Avec cela, le générateur est ensemencé une fois et peut ensuite être réutilisé à des points ultérieurs.
Les raccourcis vers la version de réensemencement d'un générateur sont également disponibles:
Xoroshiro . withThreadLocalReseeding {
...
}Ce qui est bien mieux que d'écrire:
ReseedingRandomGenerator . withThreadLocal ( createdWith : { Xoroshiro . reseeding } ) {
...
}RandomKit est très orienté vers le protocole, ce qui lui donne la possibilité d'être très flexible et modulaire.
Un protocole pour les types qui peuvent générer des valeurs aléatoires à l'aide d'un RandomGenerator .
Un protocole pour les types qui peuvent générer des valeurs aléatoires facultatives dans une plage à l'aide d'un RandomGenerator .
Int . random ( in : 0 ..< 0 , using : & randomGenerator ) // nil Un protocole pour les types qui peuvent générer des valeurs aléatoires dans une plage fermée à l'aide d'un RandomGenerator .
Int . random ( in : - 100 ... 100 , using : & randomGenerator ) // -79Un protocole pour les types qui peuvent générer des valeurs aléatoires d'une valeur de base à une autre valeur, non inclusive.
La valeur de base pour les entiers est 0. Cela signifie que l'appel random(to:using:) sur une valeur négative donnera une valeur négative aléatoire ou zéro alors qu'une valeur positive donnera une valeur positive aléatoire ou zéro.
Si value == randomBase , value sera renvoyée pour random(to:using:) .
Int . random ( to : 2 , using : & randomGenerator ) // Either 0 or 1
Int . random ( to : 0 , using : & randomGenerator ) // Always 0
Int . random ( to : 32 , using : & randomGenerator ) // 15
Int . random ( to : - 5 , using : & randomGenerator ) // -3Un protocole pour les types qui peuvent générer des valeurs aléatoires à partir d'une valeur de base à travers une autre valeur, inclusive.
Les mêmes règles concernant la valeur de base de RandomToValue s'appliquent à RandomThroughValue .
Un protocole pour les types dont les instances peuvent récupérer des éléments aléatoires.
[ " Bob " , " Cindy " , " May " , " Charles " , " Javier " ] . random ( using : & randomGenerator ) // "Charles"
" Hello " . characters . random ( using : & randomGenerator ) // "e" Certains types de fondations comme NSArray sont conformes à ce protocole.
Un protocole pour les types dont les instances peuvent avoir des éléments aléatoires récupérés à partir d'une Range<Index> .
[ 20 , 37 , 42 ] . random ( in : 1 ..< 3 , using : & randomGenerator ) // Either 37 or 42Un protocole pour les types dont les éléments peuvent être mélangés.
// Array
[ 1 , 2 , 3 , 4 , 5 ] . shuffled ( using : & randomGenerator ) // [3, 4, 1, 5, 2]
// Dictionary
[ " a " : 1 , " b " : 2 , " c " : 3 ] . shuffled ( using : & randomGenerator ) // ["a": 3, "b": 1, "c": 2] L'homologue mutable de shuffled(using:) est shuffle(using:) .
Pour de meilleures performances de mélange Array , envisagez de mélanger en place avec shuffle(using:) .
Semblable à Shuffleable , sauf qu'aucun élément n'est jamais dans sa position initiale.
Tous les types entiers natifs de Swift sont conformes aux protocoles Random- .
La fonction random(using:) crée un entier de toute valeur. Par conséquent, des valeurs négatives peuvent en résulter pour les entiers signés.
Int . random ( using : & randomGenerator ) // An Int within Int.min and Int.max
Int . random ( in : 10 ... 20 , using : & randomGenerator ) // An Int within 10 and 20 Pour créer un entier signé positif, utilisez random(to:using:) ou random(through:using:) .
Int . random ( to : 1000 , using : & randomGenerator ) // 731
Int . random ( through : 10 , using : & randomGenerator ) // 4Les entiers signés peuvent être créés à partir de n'importe quelle gamme, sans danger de débordement.
Int . random ( in : ( . min + 1000 ) ... ( . max - 200 ) , using : & randomGenerator ) // 5698527899712144154 Générez une valeur de point flottante aléatoire à partir d'une plage ou 0.0...1.0 par défaut.
Double . random ( using : & randomGenerator ) // 0.9813615573117475
Double . random ( in : - 10 ... 10 , using : & randomGenerator ) // -4.03042337718197
Float . random ( in : - 10 ... 10 , using : & randomGenerator ) // 5.167088
Float80 . random ( in : - 10 ... 10 , using : & randomGenerator ) // -3.63204542399198874 Tous les types FloatingPoint peuvent également être conformes à RandomInClosedRange hors de la boîte.
Bool.random(using:) a 50/50 chances d'être true .
Si vous avez besoin d'une probabilité différente, il y a aussi random(withWeight:using:) , qui a 1 chance de weight d'être true .
String , Character et UnicodeScalar génèrent des valeurs dans " "..."~" par défaut.
String . random ( ofLength : 10 , using : & randomGenerator ) // "}+[=Ng>$w1"
String . random ( ofLength : 10 , in : " A " ... " z " , using : & randomGenerator ) // "poUtXJIbv["
Character . random ( using : & randomGenerator ) // "#"
Character . random ( in : " A " ... " z " , using : & randomGenerator ) // "s" Un tableau de valeurs aléatoires peut être généré pour les types conformes au Random avec init(randomCount:using:) .
Des initialiseurs similaires existent pour tous les autres protocoles Random- .
let randoms = Array < Int > ( randomCount : 100 , using : & randomGenerator ) // [8845477344689834233, -957454203475087100, ...] Pour les types se conformant à UnsafeRandom , une alternative plus rapide est init(unsafeRandomCount:using:) . Cet initialiseur remplit directement le tampon plutôt que d'utiliser random(using:) .
let unsafeRandoms = Array < Int > ( unsafeRandomCount : 100 , using : & randomGenerator ) // [759709806207883991, 4618491969012429761, ...] Une référence de génération de 1000 tableaux Int aléatoires de 10000 comptes:
| Générateur | Temps (en quelques secondes) |
|---|---|
Xoroshiro | 0,0271 |
Xorshift | 0,0568 |
XorshiftStar | 0,0319 |
ChaCha | 0.2027 |
MersenneTwister | 0,0432 |
ARC4Random | 0,2416 |
DeviceRandom | 5.3348 |
Remarque: Les résultats peuvent varier en raison de divers facteurs.
Cette même référence peut être exécutée avec:
./benchmark.sh --all-generators --array 10000 --count 1000 Une Date aléatoire peut être générée entre deux valeurs Date ou TimeInterval .
La fonction random(using:) Renvoie une Date dans Date.distantPast et Date.distantFuture .
Date . random ( using : & randomGenerator ) // "Aug 28, 2006, 3:38 AM"
Date . random ( in : Date . distantPast ... Date ( ) , using : & randomGenerator ) // "Feb 7, 472, 5:40 AM" Le type Decimal est conforme à divers protocoles Random- .
La fonction random(using:) renvoie une Decimal entre 0 et 1 par défaut.
Decimal . random ( using : & randomGenerator ) // 0.87490000409886706715888973957833129437
Decimal . random ( in : 0.0 ... 10.0 , using : & randomGenerator ) // 6.5464639772070720738747790627821299859 Un nombre aléatoire peut être généré à partir d'un entier ou d'une double plage, ou 0...100 par défaut.
NSNumber . random ( using : & randomGenerator ) // 79
NSNumber . random ( in : - 50 ... 100 , using : & randomGenerator ) // -27
NSNumber . random ( in : 100 ... 200 , using : & randomGenerator ) // 149.6156950363926Une couleur aléatoire peut être générée, avec ou sans alpha aléatoire.
NSColor . random ( using : & randomGenerator ) // r 0.694 g 0.506 b 0.309 a 1.0
NSColor . random ( alpha : true , using : & randomGenerator ) // r 0.859 g 0.57 b 0.409 a 0.047
UIColor . random ( using : & randomGenerator ) // r 0.488 g 0.805 b 0.679 a 1.0
UIColor . random ( alpha : true , using : & randomGenerator ) // r 0.444 g 0.121 b 0.602 a 0.085 Parce que CGFloat est conforme à FloatingPoint , il est conforme à RandomInClosedRange comme le Double et Float .
CGFloat . random ( using : & randomGenerator ) // 0.699803650379181
CGFloat . random ( in : 0 ... 100 , using : & randomGenerator ) // 43.27969591675319Un point aléatoire peut être généré à partir de plages à l'intérieur pour x et y.
CGPoint . random ( using : & randomGenerator ) // {x 70.093 y 95.721}
CGPoint . random ( xRange : 0 ... 200 , yRange : 0 ... 10 , using : & randomGenerator ) // {x 73.795 y 0.991}Une taille aléatoire peut être générée à partir de plages à l'intérieur de la largeur et de la hauteur.
CGSize . random ( using : & randomGenerator ) // {w 3.744 h 35.932}
CGSize . random ( widthRange : 0 ... 50 , heightRange : 0 ... 400 , using : & randomGenerator ) // {w 38.271 h 239.636}Un rectangle aléatoire peut être généré à partir de plages à l'intérieur des plages pour x, y, largeur et hauteur.
CGRect . random ( using : & randomGenerator ) // {x 3.872 y 46.15 w 8.852 h 20.201}
CGRect . random ( xRange : 0 ... 50 ,
yRange : 0 ... 100 ,
widthRange : 0 ... 25 ,
heightRange : 0 ... 10 ,
using : & randomGenerator ) // {x 13.212 y 79.147 w 20.656 h 5.663}Un vecteur aléatoire peut être généré à partir de plages à l'intérieur des plages pour DX et DY.
CGVector . random ( using : & randomGenerator ) // {dx 13.992 dy 89.376}
CGVector . random ( dxRange : 0 ... 50 , dyRange : 0 ... 10 , using : & randomGenerator ) // {dx 35.224 dy 13.463}Les extensions RandomKit pour la bibliothèque Bigint de Károly sont disponibles dans RandomKitBigint.
Randomkit et ses actifs sont libérés sous la licence du MIT. Les actifs peuvent être trouvés dans la branche assets .
Des parties de ce projet utilisent le code écrit par Matt Gallagher et, en conjonction avec la licence MIT, sont autorisées avec celles trouvées ici.