2009-08-18 83 views
9

我在我的代碼(C#/ WPF)中對性能非常敏感的部分,我需要以儘可能快的方式在兩個System.TimeSpan值之間執行模運算。如何使用System.TimeSpan值實現模數運算,無需循環?

這段代碼將每秒運行數千次,我非常希望避免使用手動循環計算 - 不惜一切代價。

2周的時間跨度之間的模數的想法似乎有點怪異,所以讓我來解釋 -
說我們有
時間跨度A = 1分30秒
時間跨度B = 20秒

這裏將是常見的操作和它們的合理結果的列表:

A + B =(時間跨度)1分50秒

A - B =(時間跨度)1分10秒

A * B =沒有合理的計算方法
我們應該可以用乘以TimeSpan整數。 A * 5 =(TimeSpan)7分鐘30秒
Microsoft尚未在TimeSpans和整數之間實現乘法。

A/B =(int)4或(double)4.5
此操作不是直接在.NET框架中實現的,但它非常有意義。
有在A. 4.5 B的(4.5 * 20 = 90)

A%B =(時間跨度)10秒
鑑於合理時間跨度劃分,時間跨度模量應該是相當直接的。
A/B 確實等於(int)4 餘數(TimeSpan)10秒。商和餘數是不同的數據類型,這可能實際上是微軟沒有直接實現這一點的原因。

我需要找到一種有效的方法來計算這個沒有循環。通常我不會反對短循環,但是這些TimeSpans可能會有很大的不同。 TimeSpans之間的指數差越大,商數越大。商數越大,「分環」必須執行的迭代越多。這是我在我的應用程序的這部分中不允許的依賴項。

這樣做有什麼想法嗎?

+0

答案非常簡單。我覺得自己很笨,哈哈。謝謝! – Giffyguy 2009-08-18 18:55:16

+1

一旦你有答案,一切看起來很簡單。 – 2009-08-18 19:42:28

回答

23

乘法很容易:

TimeSpan a5 = TimeSpan.FromTicks(A.Ticks * 5); 

同樣的A/B:

double aOverB = (double)A.Ticks/B.Ticks; 

和A%B:

TimeSpan aModB = TimeSpan.FromTicks(A.Ticks % B.Ticks); 

演示:

using System; 

class Test 
{ 
    static void Main() 
    { 
     TimeSpan a = TimeSpan.FromSeconds(90); 
     TimeSpan b = TimeSpan.FromSeconds(20); 

     TimeSpan a5 = TimeSpan.FromTicks(a.Ticks * 5); 
     double aOverB = (double)a.Ticks/b.Ticks; 
     TimeSpan aModB = TimeSpan.FromTicks(a.Ticks % b.Ticks); 

     Console.WriteLine(a5); 
     Console.WriteLine(aOverB); 
     Console.WriteLine(aModB); 
    } 
} 

輸出:

00:07:30 
4.5 
00:00:10 
+0

不會產生大量垃圾等待垃圾處理嗎?用毫秒或滴答作爲長時間記錄的時間最終會更好嗎? – ADB 2009-08-18 19:03:40

+6

TimeSpan是一個結構,因此不會燃燒GC。 – user7116 2009-08-18 19:05:05

4

如果您可以將時間跨度轉換爲其代表的秒數,則可以對這些值進行修改,然後再進行轉換。

5

會像

new TimeSpan(A.Ticks % B.Ticks)) 

給你你想要的結果? Ticks會是做這項工作的合適單位嗎?也許你需要將範圍轉換爲秒或毫秒或其他東西。我不知道你的申請是什麼。

3

我不會直接與時間跨度對象做到這一點,但使用蜱能力。

就是這樣。

TimeSpan oSpan = new TimeSpan(0, 1, 20, 0, 0); 
TimeSpan oShort = new TimeSpan(0, 0, 20, 0, 0); 
long modRemainder = oSpan.Ticks % oShort.Ticks; 
TimeSpan oRemainderSpan = new TimeSpan(modRemainder); 

你可以將它凝聚成1步,但我這樣做是爲了說明。它可以很容易地做任何你想要的數學運算。

1

我能想到的最好的方法就是使用TotalSeconds屬性並對其進行取模。但是,它們是Double,允許使用小數值,因此可能無法達到您正在尋找的確切值。你總是可以得到整個部分並對它們進行模數化,但是由於你擔心速度,我擔心這可能會太慢,以至於每秒必須運行數百次的操作。