- Rust की प्रमुख random crate
randमें रोज़मर्रा के operations कई traits में बिखरे हुए हैं, इसलिए छोटे public और implementation surface तथा सुसंगत उपयोग अनुभव वाली urandom विकसित की गई - high-level operations को एक
Randomstruct में जोड़ा गया औरRngtrait को sealed किया गया, ताकि arbitrary generator support के बजाय API discoverability और internal optimization को प्राथमिकता दी जा सके - कोई नया random algorithm पेश किए बिना, Xoshiro256 के output function को use-case के हिसाब से चुनकर, 1,000
f64generate करने वाले benchmark मेंrand0.10.2 की तुलना में लगभग 31% अधिक throughput दर्ज किया गया - uniform integer sampling ने threshold को lazily compute करने वाले एक unbiased implementation से reusable और one-off paths को unified किया, और
500..20_000range benchmark में यहrandके दोनों paths से तेज़ रहा - explicit seed के raw output के लिए supported architectures और SemVer-compatible releases में reproducibility की guarantee दी जाती है, लेकिन arbitrary generator plugging और
randके विशाल distribution व third-party integration ecosystem को छोड़ा गया
एकीकृत Random API
randके उपयोगी operations कई traits में बिखरे हुए हैं- random range generation के लिए
RngExt, sequence selection के लिएIndexedRandom, और shuffling के लिएSliceRandomचाहिए rand0.10 one-off calls के लिएrand::random_rangeजैसे root-level helpers देता है- RNG handle बनाए रखना हो या selection/shuffling जैसे sequence operations इस्तेमाल करने हों, तो अब भी कई traits के methods ढूंढने पड़ते हैं
- random range generation के लिए
- prelude से imports कम हो भी जाएं, फिर भी यह जानना पड़ता है कि extension method RNG, slice या iterator में से किस type पर लागू होता है, इसलिए केवल IDE autocomplete से इसे ढूंढना मुश्किल है
- urandom high-level consumer API को एक
Randomwrapper struct में रखता हैurandom::new()सेRandom<urandom::rng::Xoshiro256Rng>बनता हैuniform,choose,shuffleको उसी object पर call किया जा सकता है- autocomplete में
random,uniform,chance,choose,shuffle,sampleआदि दिखते हैं - ये सभी inherent methods हैं, इसलिए high-level extension traits ढूंढने या import करने की ज़रूरत नहीं है
extensibility के बजाय optimization चुनने वाला sealed Rng
randlow-level RNG traits को public extension point मानता है, लेकिनurandomकाRngtrait sealed है, इसलिए supported generators crate के अंदर चुने और implement किए जाते हैं- arbitrary generator को
Randomसे plug नहीं किया जा सकता - नया generator जोड़ने के लिए
urandomखुद बदलना होगा
- arbitrary generator को
- अगर लक्ष्य बेहतर algorithm है, तो अभी role-specific defaults के रूप में Xoshiro256 और ChaCha पहले से मौजूद हैं, और recommendations भी धीरे-धीरे बदलती हैं
- बेहतर विकल्प आने पर भविष्य के major release में उसे अपनाया जा सकता है
- दूसरे projects, programming languages, legacy algorithms, special hardware या simulation-specific generators के साथ compatibility के लिए केवल generator समान होना पर्याप्त नहीं है
- uniform sampling और shuffling जैसे संबंधित algorithms भी समान होने चाहिए, इसलिए पूरे contract को implement करने वाला dedicated implementation ज़्यादा उपयुक्त है
- sealed trait की वजह से unknown generators और edge cases के लिए implementation contract design/document किए बिना
urandomमें केवल आवश्यक raw operations जोड़े जा सकते हैं- generators और algorithms को एक-दूसरे के हिसाब से specialize किया जा सकता है, जिससे
randमें उपलब्ध न होने वाली कुछ optimizations संभव होती हैं
- generators और algorithms को एक-दूसरे के हिसाब से specialize किया जा सकता है, जिससे
- ज़्यादातर applications में नए PRNG implementation की तुलना में entropy selection ज़्यादा उपयोगी है
- concrete generators native
from_seedconstructors expose करते हैं ChaCha12Rng::from_seed(seed)की तरह explicit seed वालाRandomबनाया जा सकता है- arbitrary RNG implementation स्वीकार नहीं किया जाता, लेकिन advanced users को जिन extension points की ज़रूरत पड़ने की उम्मीद है, वे बनाए रखे गए हैं
- concrete generators native
उसी algorithm से मिला performance improvement
urandomकोई नया random generation algorithm इस्तेमाल नहीं करता- 64-bit systems पर non-cryptographic use के लिए
urandom::new()औरrand::rngs::SmallRngएक ही Xoshiro256 family का उपयोग करते हैं - cryptographic use के लिए
urandom::csprng()औरrand::rngs::StdRngChaCha12 का उपयोग करते हैं - convenience function
rand::rng()का internal generator भी ChaCha12 है
- 64-bit systems पर non-cryptographic use के लिए
randका generator interface integer words और byte filling देता है, इसलिएf64चाहिए होने वाली distributions भी पूराu64मांगती हैंurandom::Rngnext_u32,next_u64के साथ-साथnext_f32औरnext_f64भी देता है- floating-point random numbers को पूरे word से कम random bits चाहिए होते हैं
- generators इन methods को सस्ते output function से override कर सकते हैं
- Xoshiro implementation state transition share करता है, लेकिन output paths अलग रखता है
u64के लिए Xoshiro256++ बनाए रखता हैu32और floating-point के लिए तेज़ Xoshiro256+ इस्तेमाल करता है, जिसके upper bits इस use-case के लिए design किए गए हैं
urandom1.0 औरrand0.10.2 से क्रमशः 1,000 random numbers generate करने वाले microbenchmark results इस प्रकार हैं- Xoshiro
u64: दोनों 814ns - Xoshiro
u32:rand836ns,urandom788ns - Xoshiro
f64:rand1,033ns,urandom788ns - ChaCha12
f64:rand2,199ns,urandom2,011ns
- Xoshiro
- Xoshiro
f64का end-to-end throughput लगभग 31% अधिक और execution time 24% कम था, लेकिन समान काम करने वालाu64path व्यावहारिक रूप से बराबर रहा - ChaCha12
next_f64को override नहीं करता, इसलिए performance broadly similar है - exact timings machine और compiler के हिसाब से बदल सकती हैं; विस्तृत conditions पूरे benchmark notes में देखी जा सकती हैं
एकीकृत uniform sampling path
- integers को range length से simple modulo करने पर bias पैदा होता है, इसलिए सही uniform integer sampling को generator output के कुछ हिस्से reject करने पड़ते हैं
- सही rejection threshold calculation में महंगा modulo operation चाहिए होता है
- sampler को बार-बार इस्तेमाल करना हो तो initial setup cost स्वीकार्य हो सकती है
- सिर्फ एक value generate करते समय यह cost अपेक्षाकृत बड़ी हो जाती है
randइस अंतर कोUniformSamplertrait से expose करता है- generated
UniformIntthreshold को पहले से compute कर bias-free sampling करता है Rng::random_rangeinitial setup से बचने के लिए अलगsample_singleयाsample_single_inclusivehook इस्तेमाल करता है- default feature में one-off shortcut path थोड़ा biased दूसरा algorithm इस्तेमाल करता है
- optional
unbiasedfeature इसे ज़्यादा complex iterative version से बदलता है
- generated
urandomthreshold को lazily compute करके reusable और one-off ranges दोनों के लिए एक ही unbiased multiply-and-reject implementation इस्तेमाल करता है- Daniel Lemire के 2018 paper Fast Random Integer Generation in an Interval में बताए गए तरीके का पालन करता है
- ज़्यादातर practical ranges में पहला candidate division से पहले return हो जाता है
- अगर पहला candidate return नहीं हो सकता, तो exact threshold compute करके बिना bias के iterate किया जाता है
- पूरी range request होने पर
range == 0exception भी handle किया जाता है
- अलग method, दूसरा algorithm, upfront setup cost या biased fast path के बिना वही implementation reusable distribution और one-off ranges संभालता है
500..20_000range से 1,000 samples निकालने वाले benchmark results इस प्रकार हैं- reusable
UniformInt:rand1,098ns,urandom950ns - one-off range:
rand1,079ns,urandom942ns
- reusable
randresults default features पर आधारित हैं, इसलिए तेज़ one-off row भी थोड़ा biased path है, जबकिurandomunbiased रहते हुए दोनों paths से तेज़ था
releases और architectures में reproducibility
urandomreproducibility को public contract का हिस्सा मानता है- same explicit seed और same low-level RNG call order दिए जाने पर deterministic generator का raw output बना रहता है
- supported architectures और SemVer-compatible releases में stability guarantee की जाती है
- 64-bit server और 32-bit WebAssembly client replay के लिए same generator base इस्तेमाल कर सकते हैं
- इस compatibility को बनाए रखने के लिए 32-bit architectures पर performance की बलि दी जाती है
- यह
randकी reproducibility policy से stronger guarantee हैrandके portable generators और sampling algorithms minor releases में output बदल सकते हैंSmallRngऔरStdRngस्पष्ट रूप से portable नहीं हैं और platform या library release के अनुसार भी बदल सकते हैं
trade-offs और कब चुनें
urandomcommon operations कोRandomमें इकट्ठा कर extension traits के बिना उन्हें आसानी से discoverable बनाता है- generator और distribution को साथ design करके सस्ता Xoshiro output path और एक unbiased uniform sampling path implement करता है
- explicit seed वाले generators की stable raw stream deterministic games और simulations में काम आ सकती है
- बदले में arbitrary generator import नहीं किए जा सकते, और
randकी बड़ी distribution list व third-party integration ecosystem भी उपलब्ध नहीं है - अगर व्यापक ecosystem चाहिए तो
randउपयुक्त है; अगर छोटा API surface, discoverability, integrated optimization और strong reproducibility policy पसंद है तोurandomचुना जा सकता है - package crates.io, API docs, और GitHub source पर देखा जा सकता है
1 टिप्पणियां
Lobste.rs टिप्पणियाँ
randको fork करने की पर्याप्त वजहें हैं, लेकिनurandomनाम सुनने में/dev/urandomसे जुड़ी किसी लाइब्रेरी जैसा लगता हैमैं समस्या-बोध से सहमत हूँ, लेकिन
pub fn new() -> Random<impl Rng + Clone>पसंद नहीं आयाअगर पूरे application को
Random<T> where T: Rngके रूप में parameterize किया जाए, तो झंझट वाला काम बढ़ जाता है, और compile time वdynसे जुड़ी समस्याएँ गंभीर हो जाती हैं। मैं बेहतर समझूँगा किstruct Randomका कोई concrete type हो, या दूसरे विकल्प के रूप मेंstruct Random<T = rng::Xoshiro256Rng>चुना जाएऐसी ही निराशा की वजह से मैं भी पहले खुद कुछ बना चुका हूँ, लेकिन वह fork नहीं है, और
randसे बहुत कम features हैंअच्छा लगा कि मेरी जैसी समस्या महसूस करने वाला कोई व्यक्ति वास्तव में उसे हल करने आगे आया। Rust में अजीब तरह से trait soup लाइब्रेरी बनवाने की प्रवृत्ति दिखती है
काम में जिन databases से मैं निपटता हूँ, उनके core data types को कम-से-कम 15 traits implement करने पड़ते हैं, जिससे autocomplete बुरी तरह बिगड़ जाता है और documentation भी उलझनभरी हो जाती है। मैंने traits की संख्या कुछ कम की, लेकिन अक्सर circular dependencies या core tests न लिख पाने जैसी समस्याओं से अटक जाता हूँ
यह लाइब्रेरी मुझे APOSD के deep interfaces और Filippo के ऐसे cryptography work दोनों की याद दिलाती है, जिन्हें गलती करना मुश्किल बनाने के लिए डिज़ाइन किया गया है, और दोनों ही बड़ी तारीफ़ हैं
urandom::new()cryptographically secure random number generator वापस नहीं करता, इसलिए यह पूरी तरह mistake-proof design नहीं है। खासकर इसलिए भी कि Linux का/dev/urandomसुरक्षित है, जिससे और भ्रम होता हैrandके एक और विकल्प के रूप में सरल और तेज़ random generatorfastrandहै। यहrandऔरurandomसे अधिक सरल है, लेकिन features भी कम हैं