11

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

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

两个 TimeSpan 之间的模数的想法可能看起来有点奇怪,所以请允许我解释一下 -
假设我们有
TimeSpan A = 1 分 30 秒
TimeSpan B = 20 秒

以下是常见操作及其合理结果的列表:

A + B = (TimeSpan)1 分 50 秒

A - B = (TimeSpan)1 分 10 秒

A * B = 没有合理的计算方法
我们应该能够将 TimeSpan 乘以一个整数。A * 5 = (TimeSpan) 7 分 30 秒
Microsoft 尚未实现 TimeSpan 和整数之间的乘法。

A / B = (int)4 或 (double)4.5
这个操作在.NET 框架中没有直接实现,但是非常有意义。
A 中有 4.5 个 B。 (4.5 * 20 = 90)

A % B = (TimeSpan) 10 秒
给定合理的 TimeSpan 划分,TimeSpan 模数应该非常简单。
A / B实际上等于 (int)4余数(TimeSpan)10 秒。商和余数是不同的数据类型,这实际上可能是微软没有直接实现这一点的原因。

我需要找到一种有效的方法来计算它而无需循环。通常我不会反对短循环,但这些 TimeSpan 可能会有很大差异。TimeSpan 之间的指数差越大,商越大。商越大,“分循环”必须执行的迭代次数就越多。这是我在应用程序的这一部分中不能允许的依赖项。

SO有什么想法吗?

4

5 回答 5

27

乘法很简单:

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
于 2009-08-18T18:51:14.197 回答
6

会像

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

给你想要的结果?蜱虫是完成这项工作的合适单位吗?也许您需要将跨度转换为秒或毫秒或其他东西。我不知道你的申请是什么。

于 2009-08-18T18:50:35.413 回答
4

如果您可以将时间跨度转换为它所代表的秒数,则可以修改这些值,然后再转换回来。

于 2009-08-18T18:49:37.633 回答
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 步,但我这样做是为了说明。它使您可以轻松轻松地进行任何您想要的数学运算。

于 2009-08-18T18:52:59.340 回答
1

我能想到的最好的方法是使用 TotalSeconds 属性并将其取模。但是,它们是 Double,允许小数值,因此可能无法达到您正在寻找的确切值。你总是可以得到整个部分并将它们取模,但由于你担心速度,我担心这对于必须每秒运行数百次的操作来说可能太慢了。

于 2009-08-18T18:55:55.607 回答