একটি এলোমেলো বুলিয়ান উত্পাদন করার দ্রুততম উপায়


87

সুতরাং সি # এ একটি এলোমেলো বাল তৈরির বিভিন্ন উপায় রয়েছে:

  • র্যান্ডম.নেক্সট () ব্যবহার করে: rand.Next(2) == 0
  • র্যান্ডম.নেক্সটডুবল () ব্যবহার করে: rand.NextDouble() > 0.5

আসলেই কি তফাত আছে? যদি তা হয় তবে কোনটির কার্যকারিতা আরও ভাল? বা অন্য কোন উপায় আছে যা আমি দেখিনি, এটি আরও দ্রুত হতে পারে?



7
আসলেই কি এই বাধা?
ব্রায়ান রাসমুসেন

4
আসলে এটি চালানো ছাড়াই (কারণ যে কোনও পদ্ধতি হাস্যকরভাবে দ্রুত হবে), আমার ধারণাটি হ'ল NextBytesবাইট অ্যারের প্রাক-জনবসতি BitArrayকরতে, সেটিকে বুলিয়ান সংগ্রহের মধ্যে পরিণত করার জন্য ব্যবহার করা এবং সেই বুলেটিয়ানগুলি Queueখালি না হওয়া অবধি পুনরুদ্ধার করা উচিত , তারপরে পুনরাবৃত্তি করুন প্রক্রিয়া. এই পদ্ধতির সাহায্যে আপনি একবারে র্যান্ডোমাইজারটি ব্যবহার করছেন, সুতরাং এটি তৈরি করা যে কোনও ওভারহেড কেবল তখনই ঘটে যখন আপনি সারিটি পুনরায় পূরণ করবেন। নিয়মিত Randomক্লাসের চেয়ে নিরাপদ র্যান্ডম নম্বর জেনারেটরের সাথে কাজ করার সময় এটি কার্যকর হতে পারে ।
জো আনোস

4
@ জোইনোস এমএস বাস্তবায়নের ক্ষেত্রে বিশৃঙ্খলা তৈরি করেছে NextBytes, তাই এটি আশ্চর্যজনকভাবে ধীর
কোডসইনচোস

4
@ কোডসইন চাওস বাহ, এটি আকর্ষণীয় - আপনি কী উল্লেখ করছেন তা দেখার জন্য আমি কেবল এটি বিচ্ছিন্ন করে দেখলাম: buffer[i] = (byte)(this.InternalSample() % 256);- আমি ধরে নিচ্ছি যে আপনি যার কথা বলছেন, তারা এলোমেলো পূর্ণসংখ্যাটি গ্রহণ করে এটিকে 3 বাইটে বিভক্ত করতে পারত , প্রায় 1/3 কাজের সাথে বাইট অ্যারে পপুলেটিং করছে। আমি ভাবছি যে এর কোনও কারণ ছিল বা এটি যদি বিকাশকারীরা কেবলমাত্র তদারকি করেন।
জো এনোস

উত্তর:


72

প্রথম বিকল্প - rand.Next(2)দৃশ্যগুলো নিম্নলিখিত কোড পিছনে, executes:

if (maxValue < 0)
{
    throw new ArgumentOutOfRangeException("maxValue",
        Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", new object[] { "maxValue" }));
}
return (int) (this.Sample() * maxValue);

এবং জন্য দ্বিতীয় বিকল্প - rand.NextDouble():

return this.Sample();

যেহেতু প্রথম বিকল্পটিতে maxValueবৈধতা, গুণ এবং ingালাই রয়েছে , দ্বিতীয় বিকল্পটি সম্ভবত দ্রুত


আপনাকে ধন্যবাদ, আমি এটাই জানতে চেয়েছিলাম।
সময়সূচী

4
আমার নিজস্ব সময় বলে যে দ্বিতীয় বিকল্পটি প্রথমটির চেয়ে প্রায় 5% দ্রুত।
রিক

61

দ্বিতীয় বিকল্পের জন্য ছোট বর্ধন :

এমএসডিএন অনুসারে

public virtual double NextDouble()

প্রত্যাবর্তন

একটি ডাবল-নির্ভুলতা ভাসমান পয়েন্ট সংখ্যা এর চেয়ে বড় বা সমান 0.0 এবং এর চেয়ে কম 1.0।

সুতরাং আপনি যদি সমানভাবে ছড়িয়ে থাকা এলোমেলো বুল চান তবে আপনার ব্যবহার করা উচিত >= 0.5

rand.NextDouble() >= 0.5

ব্যাপ্তি 1: [0.0 ... 0.5 [
পরিসীমা 2: [0.5 ... 1.0 [
| সীমা 1 | = | ব্যাপ্তি 2 |


10

দ্রুততর. পদ্ধতিটি কল করার Random.Nextক্ষেত্রে ওভারহেড কম থাকে। নীচের এক্সটেনশন পদ্ধতিটি 20% এর চেয়ে দ্রুত Random.NextDouble() > 0.5এবং 35% এর চেয়ে দ্রুত গতিতে চলে Random.Next(2) == 0

public static bool NextBoolean(this Random random)
{
    return random.Next() > (Int32.MaxValue / 2);
    // Next() returns an int in the range [0..Int32.MaxValue]
}

দ্রুততম চেয়ে দ্রুত। Randomকৌশলগুলি ব্যবহার করে আরও দ্রুত শ্রেণীর সাথে এলোমেলো বুলিয়ান তৈরি করা সম্ভব । উত্পাদিত 31 টির উল্লেখযোগ্য বিটগুলি intপরবর্তী 31 বুলিয়ান উত্পাদনের জন্য ব্যবহার করা যেতে পারে। পূর্বের হিসাবে দ্রুততম হিসাবে ঘোষিতের চেয়ে নীচে বাস্তবায়ন 40% দ্রুত।

public class RandomEx : Random
{
    private uint _boolBits;

    public RandomEx() : base() { }
    public RandomEx(int seed) : base(seed) { }

    public bool NextBoolean()
    {
        _boolBits >>= 1;
        if (_boolBits <= 1) _boolBits = (uint)~this.Next();
        return (_boolBits & 1) == 0;
    }
}

ধন্যবাদ! স্ক্রিপ্টগুলি লেখার জন্য ইউনিটিইজাইন ব্যবহারকারীদের জন্য, সিস্টেম.র্যান্ডম এবং ইউনিটিইঞ্জাইন নয় র্যান্ডম ব্যবহার করার বিষয়টি নিশ্চিত করুন, কারণ তারা একই জিনিস নয়!
ডোনকার্লিয়নে

6

আমি স্টপওয়াচ দিয়ে পরীক্ষা চালিয়েছি। 100,000 পুনরাবৃত্তি:

System.Random rnd = new System.Random();
if (rnd.Next(2) == 0)
     trues++;

সিপিইউগুলি পূর্ণসংখ্যার মতো, সুতরাং পরবর্তী (2) পদ্ধতিটি দ্রুত ছিল। 3,700 বনাম 7,500 মিমি, যা যথেষ্ট যথেষ্ট। এছাড়াও: আমি মনে করি এলোমেলো সংখ্যাগুলি বিড়ম্বনা হতে পারে, আমি ইউনিটিতে প্রতিটি ফ্রেম প্রায় 50 টি তৈরি করেছি, এমনকি একটি ক্ষুদ্র দৃশ্য যা আমার সিস্টেমটি লক্ষণীয় করে তোলে, তাই আমিও এলোমেলো একটি বুল তৈরির পদ্ধতি খুঁজে পাওয়ার আশা করছিলাম। তাই আমি চেষ্টাও করেছি

if (System.DateTime.Now.Millisecond % 2 == 0)
       trues++;

তবে 9,600 মিমি সহ স্থির ফাংশন কল করা এমনকি ধীর ছিল। একটি শট মূল্যবান। অবশেষে আমি তুলনা এড়িয়ে গিয়েছিলাম এবং কেবলমাত্র 100,000 এলোমেলো মান তৈরি করেছি, এটি নিশ্চিত করার জন্য যে ইনট বনাম ডাবল তুলনাটি অতিবাহিত সময়কে প্রভাবিত করে না, তবে ফলাফলটি বেশ একই রকম ছিল।


4
ডেটটাইম.নাউ কুখ্যাতভাবে ধীর। এটিকে দ্রুত করতে আদর্শভাবে হার্ডওয়্যার-নির্ভর সমাধানগুলি বা কমপক্ষে ওএস-নির্ভর ব্যবহার করা উচিত।
ডু-ডু-নতুন

ব্যবহার করুন DateTime.UtcNow, এটি তুলনায় অনেক দ্রুত DateTime.Now
থিওডর জৌলিয়াস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.