如何确保时间戳始终唯一?

编程入门 行业动态 更新时间:2024-10-11 03:19:29
本文介绍了如何确保时间戳始终唯一?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用时间戳对我的程序中的并发更改进行时间排序,并要求更改的每个时间戳都是唯一的.但是,我发现仅仅调用 DateTime.Now 是不够的,因为如果快速连续调用它通常会返回相同的值.

I'm using timestamps to temporally order concurrent changes in my program, and require that each timestamp of a change be unique. However, I've discovered that simply calling DateTime.Now is insufficient, as it will often return the same value if called in quick succession.

我有一些想法,但没有什么是解决此问题的最佳"解决方案.有没有我可以编写的方法来保证每次连续调用都会产生一个唯一的 DateTime?

I have some thoughts, but nothing strikes me as the "best" solution to this. Is there a method I can write that will guarantee each successive call produces a unique DateTime?

我是否应该为此使用不同的类型,也许是一个长整数?DateTime 具有明显的优势,可以轻松地将其解释为实时时间,这与增量计数器不同.

Should I perhaps be using a different type for this, maybe a long int? DateTime has the obvious advantage of being easily interpretable as a real time, unlike, say, an incremental counter.

更新:这是我最终编码为一个简单的折衷解决方案的内容,它仍然允许我使用 DateTime 作为我的时间键,同时确保每次方法的唯一性称为:

Update: Here's what I ended up coding as a simple compromise solution that still allows me to use DateTime as my temporal key, while ensuring uniqueness each time the method is called:

private static long _lastTime; // records the 64-bit tick value of the last time private static object _timeLock = new object(); internal static DateTime GetCurrentTime() { lock ( _timeLock ) { // prevent concurrent access to ensure uniqueness DateTime result = DateTime.UtcNow; if ( result.Ticks <= _lastTime ) result = new DateTime( _lastTime + 1 ); _lastTime = result.Ticks; return result; } }

因为每个滴答值只有百万分之一秒,所以这种方法只会在每秒调用 1000 万次时引入明显的时钟偏差(顺便说一下,它的执行效率足够高),这意味着它对我的目的来说是完全可以接受的.

Because each tick value is only one 10-millionth of a second, this method only introduces noticeable clock skew when called on the order of 10 million times per second (which, by the way, it is efficient enough to execute at), meaning it's perfectly acceptable for my purposes.

这是一些测试代码:

DateTime start = DateTime.UtcNow; DateTime prev = Kernel.GetCurrentTime(); Debug.WriteLine( "Start time : " + start.TimeOfDay ); Debug.WriteLine( "Start value: " + prev.TimeOfDay ); for ( int i = 0; i < 10000000; i++ ) { var now = Kernel.GetCurrentTime(); Debug.Assert( now > prev ); // no failures here! prev = now; } DateTime end = DateTime.UtcNow; Debug.WriteLine( "End time: " + end.TimeOfDay ); Debug.WriteLine( "End value: " + prev.TimeOfDay ); Debug.WriteLine( "Skew: " + ( prev - end ) ); Debug.WriteLine( "GetCurrentTime test completed in: " + ( end - start ) );

...结果:

Start time: 15:44:07.3405024 Start value: 15:44:07.3405024 End time: 15:44:07.8355307 End value: 15:44:08.3417124 Skew: 00:00:00.5061817 GetCurrentTime test completed in: 00:00:00.4950283

所以换句话说,它在半秒内生成了 1000 万个唯一时间戳,而最终结果只提前了半秒.在实际应用中,这种偏斜是不明显的.

So in other words, in half a second it generated 10 million unique timestamps, and the final result was only pushed ahead by half a second. In real-world applications the skew would be unnoticeable.

推荐答案

以下代码是获得严格升序且没有重复的时间戳序列的一种方法.

One way to get a strictly ascending sequence of timestamps with no duplicates is the following code.

与此处的其他答案相比,此答案具有以下优点:

Compared to the other answers here this one has the following benefits:

  • 这些值与实际实时值密切相关(除非在请求率非常高的极端情况下,它们会略微领先于实时值).
  • 它是无锁的,并且应该比使用 lock 语句的解决方案表现得更好.
  • 它保证升序(简单地附加一个循环计数器不会).
  • The values track closely with actual real-time values (except in extreme circumstances with very high request rates when they would get slightly ahead of real-time).
  • It's lock free and should perform better that the solutions using lock statements.
  • It guarantees ascending order (simply appending a looping a counter does not).
  • public class HiResDateTime { private static long lastTimeStamp = DateTime.UtcNow.Ticks; public static long UtcNowTicks { get { long original, newValue; do { original = lastTimeStamp; long now = DateTime.UtcNow.Ticks; newValue = Math.Max(now, original + 1); } while (Interlocked.CompareExchange (ref lastTimeStamp, newValue, original) != original); return newValue; } } }

    更多推荐

    如何确保时间戳始终唯一?

    本文发布于:2023-06-06 06:24:49,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/539058.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:时间

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!