如何在不循环的情况下使用 System.TimeSpan 值实现模数运算?

发布于 2024-08-02 15:49:24 字数 876 浏览 2 评论 0原文

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

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

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

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

A + B = (TimeSpan)1 分钟 50 秒

A - B = (TimeSpan)1 分钟 10 秒

A * B = 没有合理的计算方法< br> 我们应该能够将 TimeSpan 乘以一个整数。 A * 5 =(时间跨度)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有什么想法吗?

I'm in a very performance-sensitive portion of my code (C#/WPF), and I need to perform a modulus operation between two System.TimeSpan values in the quickest way possible.

This code will be running thousands of times per second, and I would very much prefer to avoid using a manual loop calculation - at all costs.

The idea of a modulus between two TimeSpans may seem a little weird, so allow me to explain -
Say we have
TimeSpan A = 1 Minute 30 Seconds
TimeSpan B = 20 Seconds

Here would be a list of common operations and their reasonable results:

A + B = (TimeSpan)1 Minute 50 Seconds

A - B = (TimeSpan)1 Minute 10 Seconds

A * B = No Reasonable Way to Compute
We should be able to multiply a TimeSpan by an integer. A * 5 = (TimeSpan) 7 Minutes 30 Seconds
Microsoft has not implemented multiplication between TimeSpans and integers.

A / B = (int)4 or (double)4.5
This operation is not implemented directly in the .NET framework, but it makes perfect sense.
There are 4.5 B's in A. (4.5 * 20 = 90)

A % B = (TimeSpan) 10 Seconds
Given reasonable TimeSpan division, TimeSpan modulus should be pretty straight-forward.
A / B really equals (int)4 remainder (TimeSpan)10 Seconds. The quotient and remainder are different data types, which may in fact be why Microsoft hasn't implemented this directly.

I need to find an efficient way to compute this without looping. Normally I wouldn't be opposed to a short loop, but these TimeSpans could differ greatly. The larger the exponential difference between the TimeSpans, the larger the quotient. The larger the quotient, the more iterations a "divide-loop" will have to execute. This is a dependency that I cannot allow in this part of my app.

Does SO have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

枯寂 2024-08-09 15:49:24

乘法很简单:

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

Multiplication is easy:

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

Likewise A/B:

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

And A%B:

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

Demonstration:

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);
    }
}

Output:

00:07:30
4.5
00:00:10
紧拥背影 2024-08-09 15:49:24

类似的东西

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

会给你你想要的结果吗? Ticks 是开展这项工作的合适单位吗?也许您需要将跨度转换为秒或毫秒之类的。我不知道你的申请是什么。

Would something like

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

give you the result you want? Would Ticks be the right unit to do the work? Maybe you'd need to convert the span into seconds or milliseconds or something. I don't know what your application for this is.

樱桃奶球 2024-08-09 15:49:24

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

If you can convert away from a time span to the number of seconds it represents, you can mod those values and then convert back.

如何视而不见 2024-08-09 15:49:24

我不会直接使用时间跨度对象执行此操作,而是使用刻度功能。

像这样的东西。

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 个步骤,但我这样做是为了说明。它使您可以轻松轻松地进行任何您想要的数学运算。

I wouldn't do this directly with the timespan object, but use the ticks ability.

Something like this.

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);

You can condense, it into 1 step, but I did this to illustrate. It makes it nice and easy to do any mathematical operation that you desire.

活雷疯 2024-08-09 15:49:24

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

The best I can think of is to use the TotalSeconds Property and modulo it. However, they are Double, allow for fractional values and therefore, may not reach the exact values you are seeking for. You could always get the whole portions and modulo them but since you are worried about speed, I fear this may be too slow for an operation that must run hundreds of times a second.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文