ZeN*_*eNo 0 c# algorithm bit-manipulation unique c#-4.0
我试图在DateTime滴答和增加数字的帮助下在c#中生成唯一值.伪代码:
我运行测试以生成200万个数字并插入具有唯一约束集的数据库列并且它成功运行.
以下是执行此操作的代码段:
private static long _sequence = 1;
public static long GetUniqueNumber()
{
const int timeShift = 21;
var dateTime = DateTime.Now.Ticks;
const long dateTimeMask = ~(0L) >> timeShift;
const long sequenceMask = ((~(0L) >> (64 - timeShift)));
var seq = Interlocked.Increment(ref _sequence);
var dateTimeNo = (dateTimeMask & dateTime) << timeShift;
var seqNum = (seq & sequenceMask);
var num = dateTimeNo | seqNum;
return num;
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题:1.这个逻辑是否足以产生唯一数字?我发现有些生成的数字是'-ve',我不明白.
欢迎任何帮助/建议/改进.
这个逻辑是否足以产生唯一数字
在什么范围内独特?在多台计算机/进程中AppDomain
,当然不是.在一个AppDomain
?并不是的.生成200万个数字是无关紧要的 - 这只是测试你的序列部分是否有效.(2 21刚刚超过200万.)
如果您可以在粒度(可能是~10-15ms)内拨打GetUniqueNumber
2 21 +1次,DateTime.Now
那么您将获得重复.你有没有测量过你的计算机可以称之为多快?
然后就是这些43位将在2 43个时间段内重复的事实......或者至少如果你有一个足够细粒度的时钟.(迟早,粒度会对你不利.)
我发现一些生成的数字是'-ve',我不明白.
只要dateTimeNo
设置了它的最高位(43位),你最终会得到一个long
顶部位设置 - 这意味着它将是负数.
编辑:还要注意你的换档是坏的.这个:
const long dateTimeMask = ~(0L) >> timeShift;
Run Code Online (Sandbox Code Playgroud)
执行一个符号扩展的移位 - 所以你只是以〜0L结束.
简而言之:使用Guid.NewGuid
.这就是它的用途.