Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fill an array with random numbers using threads in c#

so as said in the tile I'm trying to fill up an array of bytes with random numbers using 16 (in my case) threads, now it takes about six and a half seconds filling up an array with 500000000 bytes using one thread so the logic says that using 16 threads will be at least 10 times faster but then I tried to do this, it took 15 seconds to fill it up, what I did is I gave each thread one segment to fill in the same array

here is the code:

        static byte[] nums2 = new byte[500000000];
        static Random rnd = new Random(123);
        static void fill()
        {
            for (int i = 0; i < nums.Length; i++)
                nums[i] = (byte)rnd.Next(10);
        }

        static void fillPart(object ID)
        {
            var part = nums2.Length / Environment.ProcessorCount;
            int baseN = (int)ID * part;
            for (int i = baseN; i < baseN + part; i++)
                nums2[i] = (byte)rnd.Next(10);
            Console.WriteLine("Done! " + ID);
        }

        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            fill();
            watch.Stop();
            Console.WriteLine("it took " + watch.Elapsed);
            Console.WriteLine();

            watch.Reset();
            watch.Start();
            Thread[] threads = new Thread[Environment.ProcessorCount];
            for (int i = 0; i < Environment.ProcessorCount; i++)
            {
                threads[i] = new Thread(fillPart);
                threads[i].Start(i);
            }
            for(int i = 0; i < Environment.ProcessorCount; i++)
                threads[i].Join();

            watch.Stop();
            Console.WriteLine("it took " + watch.Elapsed);
        }
    }```
would like to understand why is it took 15 seconds or maybe what I did wrong
like image 491
user9609349 Avatar asked Apr 20 '26 00:04

user9609349


1 Answers

If it were me, I'd just:

byte[] nums = new byte[500000000];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(nums);

and be done with it.

If you really want threads:

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
var dop = 8;
var batchSize = 500000000 / dop;
var bigBytes = Enumerable.Range(0, dop).AsParallel().SelectMany(t => {
    var bytes = new byte[batchSize];
    rng.GetBytes(bytes); //This *IS* thread-safe
    return bytes;
}).ToArray();

but I suspect the time spent collating into a new array by SelectMany followed by ToArray might make this more expensive that the single-thread approach.

like image 110
spender Avatar answered Apr 22 '26 13:04

spender