Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Random data generation in Swift

License

NotificationsYou must be signed in to change notification settings

nvzqz/RandomKit

Repository files navigation

RandomKit

PlatformLanguage: Swiftdownloads
CocoaPods - RandomKitCarthageGITTER: join chatcodebeat badgeLicenseDocumented
Become a Patron!Buy me a coffee

RandomKit is a Swift framework that makes random data generation simple and easy.

Build Status

BranchStatus
masterBuild Status

Installation

Compatibility

  • Platforms:
    • macOS 10.9+
    • iOS 8.0+
    • watchOS 2.0+
    • tvOS 9.0+
    • Linux
  • Xcode 8.0+
  • Swift 3.0.2+ & 4.0

RandomKit is possibly also compatible with FreeBSD, Android, and Windows(under Cygwin) but has not been tested for those platforms.

Install Using Swift Package Manager

TheSwift Package Manager is adecentralized dependency manager for Swift.

  1. Add the project to yourPackage.swift.

    import PackageDescriptionletpackage=Package(    name:"MyAwesomeProject",    dependencies:[.Package(url:"https://github.com/nvzqz/RandomKit.git",                 majorVersion:5)])
  2. Import the RandomKit module.

    import RandomKit

Install Using CocoaPods

CocoaPods is a centralized dependency manager forObjective-C and Swift. Gohereto learn more.

  1. Add the project to yourPodfile.

    use_frameworks!pod'RandomKit','~> 5.2.3'

    If you want to be on the bleeding edge, replace the last line with:

    pod'RandomKit',:git=>'https://github.com/nvzqz/RandomKit.git'
  2. Runpod install and open the.xcworkspace file to launch Xcode.

  3. Import the RandomKit framework.

    import RandomKit

Install Using Carthage

Carthage is a decentralized dependencymanager for Objective-C and Swift.

  1. Add the project to yourCartfile.

    github "nvzqz/RandomKit"
  2. Runcarthage update and followthe additional stepsin order to add RandomKit to your project.

  3. Import the RandomKit framework.

    import RandomKit

Benchmark

Various components of RandomKit can be easily benchmarked by runningbenchmark.sh.

./benchmark.sh [FLAGS] [PROTOCOLS]

Use the--help flag for information regarding how to use it.

Note: The default count is 10000000, which is A LOT if using the--array flag.This can be changed by passing an argument into--count or-c.

Usage

Try it out for yourself! Download the repo and open 'RandomKit.playground'.

RandomGenerator

TheRandomGenerator protocol defines basic methods for generating primitivevalues and randomizing a buffer.

All provided types that conform toRandomGenerator have a staticdefaultvalue that can be passed as aninout argument to generation functions.

letvalue=Int.random(using:&Xoroshiro.default)

Available Generators

  • ARC4Random

    • Because the symbols for thearc4random family of functions aren'texported with Foundation on Linux and other platforms, they're dynamicallyloaded at runtime.
  • DeviceRandom

    • Reads from "/dev/random" or "/dev/urandom" as its source.
  • MersenneTwister

  • Xoroshiro

  • Xorshift

  • XorshiftStar

  • ChaCha

SeedableRandomGenerator

SeedableRandomGenerator is for types that can be seeded with some associatedSeed type.

RandomBytesGenerator

TheRandomBytesGenerator protocol is for types that specialize in generating aspecific type that fills up a number of bytes. For example,MersenneTwisterspecializes in generatingUInt64 whileXorshift generatesUInt32 values.

Thread Safety

For single-threaded programs, it is safe to use a global generator instance suchasXoroshiro.default as a source of randomness.

For multi-threaded programs, the thread-local instances should be used. Thisallows for different threads to use their own separate random generators withouta shared mutable state.

In the following example,randomGenerator is unique to each thread.

letrandomBytes=Xoroshiro.withThreadLocal{ randomGeneratorinreturn[UInt8](randomCount:1000, using:&randomGenerator)}

Thread-local generators are deallocated upon thread exit, so there's no need toworry about cleanup.

It's recommended to not callwithThreadLocal(_:) or get thethreadLocalpointer each individual time it's needed. Retrieving the thread-local instanceincurs avoidable overhead.

// Badletvalue=Int.random(using:&Xoroshiro.threadLocal.pointee)array.shuffle(using:&Xoroshiro.threadLocal.pointee)// GoodletthreadLocal=Xoroshiro.threadLocalletvalue=Int.random(using:&threadLocal.pointee)array.shuffle(using:&threadLocal.pointee)// BetterXoroshiro.withThreadLocal{ randomGeneratorinletvalue=Int.random(using:&randomGenerator)    array.shuffle(using:&randomGenerator)}

As a shortcut, you can even apply a function directly as a parameter.

letvalue=Xoroshiro.withThreadLocal(Int.random)

Prior tov4.4.0,thread safety could be achieved by instantiating a new seeded instance of agivenRandomGenerator type. The problem with this is that unnecessary seedingoccurs each time. With this, the generator is seeded once and can then be reusedat later points.

Shortcuts to the reseeding version of a generator are also available:

Xoroshiro.withThreadLocalReseeding{...}

Which isway better than writing:

ReseedingRandomGenerator.withThreadLocal(createdWith:{Xoroshiro.reseeding}){...}

Protocols

RandomKit is very protocol-oriented, which gives it the ability to be veryflexible and modular.

Random

A protocol for types that can generate random values using aRandomGenerator.

RandomInRange

A protocol for types that can generate optional random values within a rangeusing aRandomGenerator.

Int.random(in:0..<0, using:&randomGenerator) // nil

RandomInClosedRange

A protocol for types that can generate random values within a closed rangeusing aRandomGenerator.

Int.random(in:-100...100, using:&randomGenerator) // -79

RandomToValue

A protocol for types that can generate random values from a base value toanother value, noninclusive.

The base value for integers is 0. This means that callingrandom(to:using:) ona negative value will yield a random negative value or zero whereas a positivevalue will yield a random positive value or zero.

Ifvalue ==randomBase,value will be returned forrandom(to:using:).

Int.random(to:2, using:&randomGenerator)  // Either 0 or 1Int.random(to:0, using:&randomGenerator)  // Always 0Int.random(to:32, using:&randomGenerator)  // 15Int.random(to:-5, using:&randomGenerator)  // -3

RandomThroughValue

A protocol for types that can generate random values from a base value throughanother value, inclusive.

The same rules regarding the base value ofRandomToValue apply toRandomThroughValue.

RandomRetrievable

A protocol for types whose instances can have random elements retrieved.

["Bob","Cindy","May","Charles","Javier"].random(using:&randomGenerator)  // "Charles""Hello".characters.random(using:&randomGenerator)  // "e"

Some Foundation types likeNSArray conform to this protocol.

RandomRetrievableInRange

A protocol for types whose instances can have random elements retrieved fromwithin aRange<Index>.

[20,37,42].random(in:1..<3, using:&randomGenerator)  // Either 37 or 42

Shuffleable

A protocol for types whose elements can be shuffled.

// 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]

The mutable counterpart ofshuffled(using:) isshuffle(using:).

For betterArray shuffling performance, consider shuffling in-place withshuffle(using:).

UniqueShuffleable

Similar toShuffleable, except no element is ever in its initial position.

Swift Types

Integers

All of Swift's native integer types conform to theRandom- protocols.

Therandom(using:) function creates an integer of any value. As a result,negative values can result for signed integers.

Int.random(using:&randomGenerator)               // An Int within Int.min and Int.maxInt.random(in:10...20, using:&randomGenerator)  // An Int within 10 and 20

To create a positive signed integer, userandom(to:using:) orrandom(through:using:).

Int.random(to:1000, using:&randomGenerator)     // 731Int.random(through:10, using:&randomGenerator)  // 4

Signed integers can be created from any range, without danger of overflow.

Int.random(in:(.min+1000)...(.max-200), using:&randomGenerator)  // 5698527899712144154

Floating Point Numbers

Generate a random floating point value from within a range or0.0...1.0 bydefault.

Double.random(using:&randomGenerator)                 //  0.9813615573117475Double.random(in:-10...10, using:&randomGenerator)  // -4.03042337718197Float.random(in:-10...10, using:&randomGenerator)  //  5.167088Float80.random(in:-10...10, using:&randomGenerator)  // -3.63204542399198874

AllFloatingPoint types can also conform toRandomInClosedRangeout-of-the-box.

Bool

Bool.random(using:) has a 50/50 chance of beingtrue.

If you need different probability, there's alsorandom(withWeight:using:),which has 1 inweight chance of beingtrue.

String, Character, and UnicodeScalar

String,Character, andUnicodeScalar generate values within" "..."~" bydefault.

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"

Arrays

An array of random values can be generated for types conforming toRandom withinit(randomCount:using:).

Similar initializers exist for all otherRandom- protocols.

letrandoms=Array<Int>(randomCount:100, using:&randomGenerator)  // [8845477344689834233, -957454203475087100, ...]

For types conforming toUnsafeRandom, a faster alternative isinit(unsafeRandomCount:using:).This initializer fills the buffer directly rather than usingrandom(using:).

letunsafeRandoms=Array<Int>(unsafeRandomCount:100, using:&randomGenerator)  // [759709806207883991, 4618491969012429761, ...]
Arrays Benchmark

A benchmark of generating 1000 randomInt arrays of 10000 count:

GeneratorTime (in seconds)
Xoroshiro0.0271
Xorshift0.0568
XorshiftStar0.0319
ChaCha0.2027
MersenneTwister0.0432
ARC4Random0.2416
DeviceRandom5.3348

Note: Results may vary due to various factors.

This same benchmark can be run with:

./benchmark.sh --all-generators --array 10000 --count 1000

Foundation Types

Date

A randomDate can be generated between twoDate orTimeInterval values.

The defaultrandom(using:) function returns aDate withinDate.distantPast andDate.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

TheDecimal type conforms to variousRandom- protocols.

Therandom(using:) function returns aDecimal between 0 and 1 by default.

Decimal.random(using:&randomGenerator)                  // 0.87490000409886706715888973957833129437Decimal.random(in:0.0...10.0, using:&randomGenerator)  // 6.5464639772070720738747790627821299859

NSNumber

A random number can be generated from within an integer or double range, or0...100 by default.

NSNumber.random(using:&randomGenerator)                 // 79NSNumber.random(in:-50...100, using:&randomGenerator)  // -27NSNumber.random(in:100...200, using:&randomGenerator)  // 149.6156950363926

Cocoa and UIKit Types

NSColor and UIColor

A random color can be generated, with or without random alpha.

NSColor.random(using:&randomGenerator)              // r 0.694 g 0.506 b 0.309 a 1.0NSColor.random(alpha:true, using:&randomGenerator) // r 0.859 g 0.57  b 0.409 a 0.047UIColor.random(using:&randomGenerator)              // r 0.488 g 0.805 b 0.679 a 1.0UIColor.random(alpha:true, using:&randomGenerator) // r 0.444 g 0.121 b 0.602 a 0.085

CoreGraphics Types

CGFloat

BecauseCGFloat conforms toFloatingPoint, it conforms toRandomInClosedRange just like howDouble andFloat do.

CGFloat.random(using:&randomGenerator)               // 0.699803650379181CGFloat.random(in:0...100, using:&randomGenerator)  // 43.27969591675319

CGPoint

A random point can be generated from within ranges for x and 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

A random size can be generated from within ranges for width and height.

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}

CGRect

A random rectangle can be generated from within ranges for x, y, width, andheight.

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}

CGVector

A random vector can be generated from within ranges for dx and 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}

Extra

RandomKit extensions for Károly'sBigInt library are available inRandomKitBigInt.

License

RandomKit and its assets are released under theMIT License. Assetscan be found in theassetsbranch.

Parts of this project utilize code written byMatt Gallagher and, in conjunctionwith the MIT License, are licensed with that foundhere.


[8]ページ先頭

©2009-2025 Movatter.jp