DEV Community

Cover image for Optimizing GUID Generation Step by Step
Mehran Davoudi
Mehran Davoudi

Posted on • Edited on

Optimizing GUID Generation Step by Step

Consider you need to create 2,000,000 GUIDs per second. And believe me, you need it to be so fast!
In this post, I'm going to write a simple code and then optimize it step by step.

This is the first code most developers would start with:

List<Guid> Loop_List_Simple()
{
    var list = new List<Guid>();
    for (var i = 1; i <= 2_000_000; i++)
        list.Add(Guid.NewGuid());

    return list;
}

// Elapsed time: 212ms
Enter fullscreen mode Exit fullscreen mode

It's just a simple loop that generates and adds 2 million GUIDs to the list. Using the benchmarking library on my computer, it shows that it takes 212ms to run this code.

The first optimization we could apply, is to make the list a fixed-size one:

List<Guid> Loop_List_Fixed_Capacity()
{
    var list = new List<Guid>(2_000_000);
    for (var i = 0; i < 2_000_000; i++)
        list.Add(Guid.NewGuid());

   return list;
}

// Elapsed time: 197ms
Enter fullscreen mode Exit fullscreen mode

That was a little better, but not that much: 212ms to 197ms.

Now let's bring the Linq in, and see what happens:

List<Guid> Linq_Simple() 
{
     return Enumerable
         .Range(1, size)
         .Select(n => Guid.NewGuid())
         .ToList();
}

// Elapsed time: 197ms
Enter fullscreen mode Exit fullscreen mode

Now it takes 197ms again, not any better. But we want more, absolutely!

Time to add some parallelism to our code. We will do it by adding a simple .AsParallel() to our LINQ:

List<Guid> Linq_AsParallel()
{
    return Enumerable
        .Range(1, size)
        .AsParallel()
        .Select(n => Guid.NewGuid())
        .ToList();
}

// Elapsed time: 87ms
Enter fullscreen mode Exit fullscreen mode

Wowwwww... It took just 87ms that's huuuuge improvement. But wait we can get more!

This time we are going to use Parallel.ForEAch method which is a part of PLINQ:

List<Guid> Linq_Parallel()
{
    var list = new Guid[size];
    Parallel.ForEach(list, (_, _, index) =>
    {
        list[index] = Guid.NewGuid();
    });

    return list.ToList();
}

// Elapsed time: 45ms
Enter fullscreen mode Exit fullscreen mode

A very big wowwwwww, can you believe it!? We have reached to 45ms, 5X faster than 212ms!!!

Summary

Well, we just finished our journey. We started our journey with a piece of code which took 212ms and finished with a code which took 45ms We have made it about 5X Faster!. Here are the final results using BenchmarkDotNet:

Optimizing Guid Generation

Also, the benchmarking code is available here on my GitHub.

Top comments (4)

Collapse
 
dotnetvato profile image
Raymond

Nice. Love the explanation @mehrandvd πŸ‘

Collapse
 
fatemehfathollahi profile image
Fatemeh Fathollahi

Amazing

Collapse
 
hamedhajiloo profile image
Hamed Hajiloo

It was very good πŸ‘

Collapse
 
msynk profile image
Saleh Yusefnejad

nice article @mehrandvd πŸ‘