RandomKit هو إطار سريع يجعل توليد البيانات العشوائية بسيطة وسهلة.
| فرع | حالة |
|---|---|
master |
ربما يكون RandomKit متوافقًا أيضًا مع FreeBSD و Android و Windows (تحت Cygwin) ولكن لم يتم اختباره لتلك المنصات.
مدير الحزمة Swift هو مدير التبعية اللامركزية لـ SWIFT.
أضف المشروع إلى Package.swift الخاصة بك.
import PackageDescription
let package = Package (
name : " MyAwesomeProject " ,
dependencies : [
. Package ( url : " https://github.com/nvzqz/RandomKit.git " ,
majorVersion : 5 )
]
)استيراد وحدة RandomKit.
import RandomKitCocoapods هو مدير تبعية مركزي لـ Objective-C و Swift. اذهب هنا لمعرفة المزيد.
أضف المشروع إلى podfile الخاص بك.
use_frameworks!
pod 'RandomKit' , '~> 5.2.3'إذا كنت تريد أن تكون على حافة النزيف ، استبدل السطر الأخير بـ:
pod 'RandomKit' , :git => 'https://github.com/nvzqz/RandomKit.git' قم بتشغيل pod install وفتح ملف .xcworkspace لبدء Xcode.
استيراد إطار RandomKit.
import RandomKitقرطاج هو مدير التبعية اللامركزية لـ Objective-C و Swift.
أضف المشروع إلى Cartfile الخاص بك.
github "nvzqz/RandomKit"
قم بتشغيل carthage update واتبع الخطوات الإضافية من أجل إضافة RandomKit إلى مشروعك.
استيراد إطار RandomKit.
import RandomKit يمكن تحديد مكونات مختلفة من RandomKit بسهولة عن طريق تشغيل benchmark.sh .
./benchmark.sh [FLAGS] [PROTOCOLS] استخدم علامة --help للحصول على معلومات تتعلق بكيفية استخدامه.
ملاحظة: العدد الافتراضي هو 10000000 ، وهو كثيرًا إذا كان يستخدم علامة --array . يمكن تغيير هذا عن طريق تمرير وسيطة إلى --count -c .
جربها بنفسك! قم بتنزيل repo وافتح "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 ) قبل v4.4.0 ، يمكن تحقيق سلامة الخيط عن طريق إنشاء مثيل جديد مصنّف من نوع من RandomGenerator معين. المشكلة في ذلك هي أن البذر غير الضروري يحدث في كل مرة. مع هذا ، يتم زرع المولد مرة واحدة ويمكن إعادة استخدامه في نقاط لاحقة.
تتوفر أيضًا اختصارات لإعادة إعادة البيع من المولد:
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 ، باستثناء عدم وجود عنصر في وضعه الأولي.
تتوافق جميع أنواع عدد صحيح من Swift الأصلي مع البروتوكولات 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:) لديه فرصة 50/50 true .
إذا كنت بحاجة true احتمال مختلف ، فهناك أيضًا random(withWeight:using:) ، والتي لديها فرصة واحدة في weight .
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 والعرض والارتفاع.
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}تتوفر امتدادات RandomKit لمكتبة Bigint في Károly في RandomKitBigint.
يتم إصدار RandomKit وأصولها بموجب ترخيص معهد ماساتشوستس للتكنولوجيا. يمكن العثور على الأصول في فرع assets .
تستخدم أجزاء من هذا المشروع الكود الذي كتبه مات غالاغر ، وفي ارتباط رخصة معهد ماساتشوستس للتكنولوجيا ، يتم ترخيصه مع ذلك الموجود هنا.