我正在开发一个C#库,它将创建大量的小对象作为正常操作的一部分(想想编译器中的AST节点(。我想以一种不会妨碍性能的方式为每个实例分配一个唯一的标识符(在程序中是唯一的,而不是全局唯一的(。对象是不可变的,并且可以在线程之间共享,因此id需要在线程之间是唯一的。
以下是我正在考虑的一些选项:
- 使用静态int或long,并通过调用
Interlocked.Increment()
获得每个新id - 使用
Guid.NewGuid()
生成ID - 使用具有
[ThreadStatic]
属性的静态int或long字段,然后根据当前线程的ManagedThreadId
属性生成字符串id,并根据线程本地计数器生成下一个值
其中一个会比其他的更具表演性吗?有更好的方法吗?
谢谢!
编辑:
我运行了一个快速基准测试,得到了以下结果:
- 0.19秒(int和long基本相同(
- 1.1秒
- 3.5秒
这似乎强烈指向使用Interlocked
。然而,在多线程场景中,Interlocked
是否存在速度减慢的风险?
Interlocked.Increment
的工作原理是确保对++
的调用作为原子操作进行。这意味着另一个线程无法获得中间变量,这可能会在使用++
时发生。
唯一的性能问题是需要同步存储变量的内存,请注意,正如您的测试所显示的那样,这种性能成本应该可以忽略不计。