C# 如何在C语言中为对象指定唯一的ID#
我正在开发一个C#库,作为正常操作的一部分,它将创建大量的小对象(想想编译器中的AST节点)。我希望以不会影响性能的方式为每个实例分配一个唯一标识符(在程序中是唯一的,而不是全局唯一的)。对象是不可变的,并且可以跨线程共享,因此id需要跨线程唯一 以下是我正在考虑的一些选择:C# 如何在C语言中为对象指定唯一的ID#,c#,guid,thread-local,unique-id,interlocked-increment,C#,Guid,Thread Local,Unique Id,Interlocked Increment,我正在开发一个C#库,作为正常操作的一部分,它将创建大量的小对象(想想编译器中的AST节点)。我希望以不会影响性能的方式为每个实例分配一个唯一标识符(在程序中是唯一的,而不是全局唯一的)。对象是不可变的,并且可以跨线程共享,因此id需要跨线程唯一 以下是我正在考虑的一些选择: 使用静态int或long,通过调用Interlocked.Increment() 使用Guid.NewGuid()生成ID 使用带有[ThreadStatic]属性的静态int或long字段,然后从当前线程的Managed
Interlocked.Increment()
Guid.NewGuid()
生成ID[ThreadStatic]
属性的静态int或long字段,然后从当前线程的ManagedThreadId
属性生成字符串id,并从线程本地计数器生成下一个值我运行了一个快速基准测试,得到了以下结果:
这似乎强烈地指向使用
联锁的。但是,在多线程场景中是否存在联锁
速度减慢的风险?联锁。增量
通过确保对++
的调用作为原子操作来工作。这意味着另一个线程无法获取中间变量,使用++
可能会发生这种情况
唯一的性能问题是需要同步存储变量的内存,请注意,正如您的测试所显示的那样,这种性能成本应该可以忽略不计。在我看来,您的(1)是解决所述问题的最佳方法。Increment()是超高速的。只要生成的数量不超过2^31个即可我一直使用CombGuid——它们基于当前的日期/时间,所以除非您的代码每秒生成数千个id——否则几乎不可能发生冲突。有关代码,请参阅本文@杰伊:嗯,对于那些只需要在一个程序上运行一次特定的程序就可以实现的东西来说,这是一个很大的开销。选项1。由于您不需要全局guid,所以guid是一种浪费resources@MatthewWatson-看起来很慢,但没那么糟。在我的机器上,生成一百万个guid需要0.1秒,生成一百万个combguid需要1秒。因此,它的速度大约是生成Guid的10倍,但它很有用,因为它们几乎肯定是唯一的。只是把它扔出去作为一种选择!