C# 如何使用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

我的代码(C#/WPF)对性能非常敏感,我需要以最快的方式在两个System.TimeSpan值之间执行模数运算

这段代码每秒将运行数千次,我非常希望避免使用手动循环计算——不惜一切代价

两个时间跨度之间的模数的想法可能有点奇怪,所以请允许我解释-
说我们有
时间跨度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。