Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I achieve a modulus operation with System.TimeSpan values, without looping?

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?

like image 406
Giffyguy Avatar asked Aug 18 '09 18:08

Giffyguy


People also ask

How does TimeSpan work?

A TimeSpan object represents a time interval (duration of time or elapsed time) that is measured as a positive or negative number of days, hours, minutes, seconds, and fractions of a second. The TimeSpan structure can also be used to represent the time of day, but only if the time is unrelated to a particular date.


1 Answers

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
like image 137
Jon Skeet Avatar answered Oct 23 '22 14:10

Jon Skeet