C# 如何使用System.TimeSpan值实现模运算而不发生循环?
我的代码(C#/WPF)对性能非常敏感,我需要以最快的方式在两个System.TimeSpan值之间执行模数运算 这段代码每秒将运行数千次,我非常希望避免使用手动循环计算——不惜一切代价 两个时间跨度之间的模数的想法可能有点奇怪,所以请允许我解释-C# 如何使用System.TimeSpan值实现模运算而不发生循环?,c#,.net,performance,math,modulo,C#,.net,Performance,Math,Modulo,我的代码(C#/WPF)对性能非常敏感,我需要以最快的方式在两个System.TimeSpan值之间执行模数运算 这段代码每秒将运行数千次,我非常希望避免使用手动循环计算——不惜一切代价 两个时间跨度之间的模数的想法可能有点奇怪,所以请允许我解释- 说我们有 时间跨度A=1分30秒 时间跨度B=20秒 以下是常见操作及其合理结果的列表: A+B=(时间跨度)1分50秒 A-B=(时间跨度)1分10秒 A*B=没有合理的计算方法 我们应该能够将时间跨度乘以整数。A*5=(时间跨度)7分30秒 Mi
说我们有
时间跨度A=1分30秒
时间跨度B=20秒 以下是常见操作及其合理结果的列表: A+B=(时间跨度)1分50秒 A-B=(时间跨度)1分10秒 A*B=没有合理的计算方法
我们应该能够将时间跨度乘以整数。A*5=(时间跨度)7分30秒
Microsoft尚未实现时间跨度和整数之间的乘法 A/B=(整数)4或(双倍)4.5
此操作不是直接在.NET framework中实现的,但它非常有意义。
A中有4.5个B(4.5*20=90) A%B=(时间跨度)10秒
给定合理的时间跨度划分,时间跨度模数应该非常直接。
A/B实际上等于(int)4余数(TimeSpan)10秒。商和余数是不同的数据类型,这可能是微软没有直接实现这一点的原因 我需要找到一种有效的方法来计算这个,而不需要循环。通常我不会反对短循环,但这些时间跨度可能会有很大差异。时间跨度之间的指数差越大,商越大。商越大,“除法循环”必须执行的迭代就越多。这是我在我的应用程序的这一部分中不允许的依赖项
你有什么想法吗?如果你可以将时间跨度转换为它所代表的秒数,你可以修改这些值,然后再转换回来。你想
new TimeSpan( A.Ticks % B.Ticks))
给你想要的结果?蜱虫是做这项工作的合适单位吗?也许你需要把时间跨度转换成秒或毫秒之类的。我不知道你的申请是什么。乘法很简单:
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
我不会直接对timespan对象执行此操作,而是使用ticks功能 像这样的
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);
你可以把它浓缩成一个步骤,但我这样做是为了说明。它使做任何你想要的数学运算变得非常简单。我能想到的最好办法就是使用TotalSeconds属性并对其进行模化。但是,它们是双精度的,允许使用分数值,因此可能无法达到您所寻求的精确值。你总是可以得到整个部分并对它们进行模块化,但由于你担心速度,我担心这对于一个每秒必须运行数百次的操作来说可能太慢了。答案非常简单。我觉得自己像个傻瓜,哈哈。非常感谢!一旦你找到了答案,一切看起来都很简单。这难道不会产生大量等待垃圾处理的对象吗?最后,使用毫秒或滴答作为长时间来跟踪时间不是更好吗?TimeSpan是一个结构,因此不会烧坏GC。