Randomkit - это быстрая структура, которая делает случайную генерацию данных простым и легким.
| Ветвь | Статус |
|---|---|
master |
Randomkit, возможно, также совместим с FreeBSD, Android и Windows (под Cygwin), но не был протестирован на эти платформы.
Swift Package Manager является децентрализованным менеджером зависимостей для Swift.
Добавьте проект в свой Package.swift . Swift.
import PackageDescription
let package = Package (
name : " MyAwesomeProject " ,
dependencies : [
. Package ( url : " https://github.com/nvzqz/RandomKit.git " ,
majorVersion : 5 )
]
)Импортируйте модуль Randomkit.
import RandomKitКокоподы являются централизованным менеджером зависимостей для Objective-C и Swift. Иди сюда, чтобы узнать больше.
Добавьте проект в свой Podfile.
use_frameworks!
pod 'RandomKit' , '~> 5.2.3'Если вы хотите быть на кровотечении, замените последнюю линию:
pod 'RandomKit' , :git => 'https://github.com/nvzqz/RandomKit.git' Запустите pod install и откройте файл .xcworkspace для запуска XCode.
Импортируйте структуру случайных.
import RandomKitКарфаген является децентрализованным менеджером зависимостей для Objective-C и Swift.
Добавьте проект в свой Cartfile.
github "nvzqz/RandomKit"
Запустите carthage update и выполните дополнительные шаги, чтобы добавить randomkit в ваш проект.
Импортируйте структуру случайных.
import RandomKit Различные компоненты Randomkit могут быть легко оценивают запуск benchmark.sh .
./benchmark.sh [FLAGS] [PROTOCOLS] Используйте флаг --help для информации о том, как его использовать.
Примечание. Подсчет по умолчанию составляет 10000000, что очень много, если использовать флаг --array . Это можно изменить, передавая аргумент в --count или -c .
Попробуйте сами! Загрузите репо и откройте 'randomkit.playground'.
Протокол RandomGenerator определяет основные методы для генерации примитивных значений и рандомизации буфера.
Все предоставленные типы, которые соответствуют RandomGenerator , имеют статическое значение default , которое может быть передано в качестве inout аргумента функциям генерации.
let value = Int . random ( using : & Xoroshiro . default ) ARC4Random
arc4random не экспортируются с основанием на Linux и других платформах, они динамически загружаются во время выполнения. DeviceRandom
MersenneTwister
Xoroshiro
Xorshift
XorshiftStar
ChaCha
SeedableRandomGenerator предназначен для типов, которые могут быть посеяны с помощью некоторого ассоциированного типа Seed .
Протокол RandomBytesGenerator предназначена для типов, которые специализируются на создании определенного типа, который заполняет несколько байтов. Например, MersenneTwister специализируется на создании UInt64 , в то время как Xorshift генерирует значения UInt32 .
Для однопоточных программ безопасно использовать экземпляр глобального генератора, такой как Xoroshiro.default в качестве источника случайности.
Для многопоточных программ следует использовать ниточные экземпляры. Это позволяет различным потокам использовать свои отдельные случайные генераторы без общего изменяемого состояния.
В следующем примере randomGenerator уникален для каждого потока.
let randomBytes = Xoroshiro . withThreadLocal { randomGenerator in
return [ UInt8 ] ( randomCount : 1000 , using : & randomGenerator )
}Торговые генераторы складываются на выходе из потока, поэтому нет необходимости беспокоиться о очистке.
Рекомендуется не вызовать withThreadLocal(_:) или получать threadLocal указатель каждый отдельный момент, когда это необходимо. Получение ниточного экземпляра приводит к предотвращению накладных расходов.
// 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 )
}В качестве ярлыка вы можете даже применить функцию непосредственно в качестве параметра.
let value = Xoroshiro . withThreadLocal ( Int . random ) До v.4.4.0 безопасность потока может быть достигнута путем создания создания нового посевного экземпляра заданного типа RandomGenerator . Проблема в том, что ненужное посева происходит каждый раз. При этом генератор выселяется один раз, а затем может быть использован повторно в более поздних точках.
Также доступны ярлыки для версии Reseeding a Generator:
Xoroshiro . withThreadLocalReseeding {
...
}Что намного лучше, чем писать:
ReseedingRandomGenerator . withThreadLocal ( createdWith : { Xoroshiro . reseeding } ) {
...
}Randomkit очень ориентирован на протокол, что дает ему возможность быть очень гибким и модульным.
Протокол для типов, который может генерировать случайные значения с использованием RandomGenerator .
Протокол для типов, который может генерировать дополнительные случайные значения в диапазоне, используя RandomGenerator .
Int . random ( in : 0 ..< 0 , using : & randomGenerator ) // nil Протокол для типов, который может генерировать случайные значения в закрытом диапазоне, используя RandomGenerator .
Int . random ( in : - 100 ... 100 , using : & randomGenerator ) // -79Протокол для типов, который может генерировать случайные значения от базового значения к другому значению, не инкурентное.
Базовое значение для целых чисел составляет 0. Это означает, что вызов random(to:using:) При отрицательном значении даст случайное отрицательное значение или ноль, тогда как положительное значение даст случайное положительное значение или ноль.
Если value == randomBase , value будет возвращено для 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 ) // -3Протокол для типов, который может генерировать случайные значения из базового значения через другое значение, включительно.
Те же правила, касающиеся базового значения RandomToValue применяются к RandomThroughValue .
Протокол для типов, чьи экземпляры могут иметь случайные элементы.
[ " Bob " , " Cindy " , " May " , " Charles " , " Javier " ] . random ( using : & randomGenerator ) // "Charles"
" Hello " . characters . random ( using : & randomGenerator ) // "e" Некоторые типы фундамента, такие как NSArray соответствуют этому протоколу.
Протокол для типов, чьи экземпляры могут иметь случайные элементы, извлеченные из Range<Index> .
[ 20 , 37 , 42 ] . random ( in : 1 ..< 3 , using : & randomGenerator ) // Either 37 or 42Протокол для типов, элементы которых можно перетасовать.
// 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] Изменяемый аналог shuffled(using:) - это shuffle(using:) .
Для лучшего Array перемещения производительности, рассмотрите возможность перетасовать на месте с помощью shuffle(using:) .
Подобно Shuffleable , за исключением того, что ни один элемент никогда не находится в его начальном положении.
Все нативные типы целых чисел Свифта соответствуют Random- протоколам.
random(using:) функция создает целое число из любого значения. В результате отрицательные значения могут привести к подписанным целым числам.
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 Чтобы создать положительное целое число подписанного, используйте random(to:using:) или random(through:using:) .
Int . random ( to : 1000 , using : & randomGenerator ) // 731
Int . random ( through : 10 , using : & randomGenerator ) // 4Подписанные целые числа могут быть созданы из любого диапазона без опасности переполнения.
Int . random ( in : ( . min + 1000 ) ... ( . max - 200 ) , using : & randomGenerator ) // 5698527899712144154 Создайте случайное значение с плавающей запятой изнутри диапазона или 0.0...1.0 по умолчанию.
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 Все типы FloatingPoint также могут соответствовать RandomInClosedRange за пределами коробки.
Bool.random(using:) имеет вероятность того, что true .
Если вам нужна другая вероятность, есть также random(withWeight:using:) , у которого есть 1 в weight шанс быть true .
String , Character и UnicodeScalar генерируют значения внутри " "..."~" по умолчанию.
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" Массив случайных значений может быть сгенерирован для типов, соответствующих Random с init(randomCount:using:) .
Подобные инициализаторы существуют для всех других Random- протоколов.
let randoms = Array < Int > ( randomCount : 100 , using : & randomGenerator ) // [8845477344689834233, -957454203475087100, ...] Для типов, соответствующих UnsafeRandom , более быстрой альтернативой является init(unsafeRandomCount:using:) . Этот инициализатор заполняет буфер напрямую, а не использует random(using:) .
let unsafeRandoms = Array < Int > ( unsafeRandomCount : 100 , using : & randomGenerator ) // [759709806207883991, 4618491969012429761, ...] Оценка генерации 1000 случайных массивов Int 10000 счетов:
| Генератор | Время (в секунды) |
|---|---|
Xoroshiro | 0,0271 |
Xorshift | 0,0568 |
XorshiftStar | 0,0319 |
ChaCha | 0,2027 |
MersenneTwister | 0,0432 |
ARC4Random | 0,2416 |
DeviceRandom | 5.3348 |
Примечание. Результаты могут варьироваться в зависимости от различных факторов.
Этот же эталон можно запустить с:
./benchmark.sh --all-generators --array 10000 --count 1000 Случайная Date может быть получена между двумя значениями Date или TimeInterval .
random(using:) Функция возвращает Date в течение Date.distantPast 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" Decimal тип соответствует различным Random- протоколам.
random(using:) Функция возвращает Decimal от 0 до 1 по умолчанию.
Decimal . random ( using : & randomGenerator ) // 0.87490000409886706715888973957833129437
Decimal . random ( in : 0.0 ... 10.0 , using : & randomGenerator ) // 6.5464639772070720738747790627821299859 Случайное число может быть сгенерировано из целочисленного или двойного диапазона, или 0...100 по умолчанию.
NSNumber . random ( using : & randomGenerator ) // 79
NSNumber . random ( in : - 50 ... 100 , using : & randomGenerator ) // -27
NSNumber . random ( in : 100 ... 200 , using : & randomGenerator ) // 149.6156950363926Можно сгенерировать случайный цвет, со случайной альфа или без него.
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 Поскольку CGFloat соответствует FloatingPoint , он соответствует RandomInClosedRange так же, как Double и Float .
CGFloat . random ( using : & randomGenerator ) // 0.699803650379181
CGFloat . random ( in : 0 ... 100 , using : & randomGenerator ) // 43.27969591675319Случайная точка может быть сгенерирована из диапазонов для x и 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}Случайный размер может быть получен из диапазонов по ширине и высоте.
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}Случайный прямоугольник может генерироваться из диапазонов для x, y, y, width и высоты.
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}Случайный вектор может быть получен из диапазонов для DX и 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}Случайные расширения для библиотеки Bigint в Кароли доступны в Randomkitbigint.
Randomkit и его активы выпускаются по лицензии MIT. Активы можно найти в филиале assets .
Части этого проекта используют код, написанный Мэттом Галлахером и в сочетании с лицензией MIT, лицензированы с тем, что найдено здесь.