I am working on a C# library that will create tons of small objects as part of normal operation (think AST nodes in a compiler). I'd like to assign each instance a unique identifier (unique within the program, not globally unique) in a way that won't hinder performance. The objects are immutable, and can be shared across threads, so the id needs to be unique across threads.
Here are some options I'm considering:
- Use a static int or long, and get each new id via calls to
Interlocked.Increment()
- Use
Guid.NewGuid()
to generate ids - Use a static int or long field with the
[ThreadStatic]
attribute, and then make a string id from the current thread'sManagedThreadId
property and the next value from the thread-local counter.
Will one of these be more performant than the others? Is there a better way to do this?
Thanks!
EDIT:
I ran a quick benchmark and got the following results:
- 0.19 seconds (int vs. long were basically the same)
- 1.1 seconds
- 3.5 seconds
This seems to point strongly towards using Interlocked
. However, is there any risk of Interlocked
slowing down in multithreaded scenarios?
Interlocked.Increment
works by ensuring that the call to++
happens as an atomic operation. That means that there is no way for another thread to get the intermediate variable, which could happen using++
.The only performance issue is the need to synchronize the memory that the variable is stored in, note that this performance cost should be negligible, as your testing seems to show.