2009-08-18 11 views
9

Jestem w bardzo wrażliwym na wydajność fragmencie mojego kodu (C#/WPF) i potrzebuję wykonać operację modulus pomiędzy dwiema wartościami System.TimeSpan w najszybszy możliwy sposób.Jak mogę uzyskać operację modułem z wartościami System.TimeSpan, bez pętli?

Ten kod będzie działał tysiące razy na sekundę, a ja zdecydowanie wolałbym uniknąć ręcznego obliczania pętli - za wszelką cenę.

Pomysł module między dwoma TimeSpans może wydawać się trochę dziwne, więc pozwólcie mi wyjaśnić -
że mamy
TimeSpan A = 1 minuta 30 sekund
TimeSpan B = 20 sekund

Tutaj miałaby postać listy typowych operacji i rozsądnych wyników:

a + B = (TimeSpan) 1 minuta 50 sekund

a - B = (TimeSpan) 1 minuta 10 sekund

A * B = Nie ma uzasadnionego sposobu obliczania
Mamy powinniśmy móc pomnożyć TimeSpan przez liczbę całkowitą. A * 5 = (TimeSpan) 7 minut 30 sekund
Firma Microsoft nie zaimplementowała mnożenia między TimeSpans a liczbami całkowitymi.

A/B = (int) 4 lub (podwójne) 4.5
Ta operacja nie jest zaimplementowana bezpośrednio w środowisku .NET, ale ma sens.
Istnieje 4,5 B w A (4,5 * 20 = 90)

A% B = (zakresu czasu) 10 sekund
względu rozsądny podział TimeSpan, TimeSpan moduł powinien być bardzo prosta.
A/B naprawdę równa się (int) 4 pozostałość (TimeSpan) 10 sekund. Iloraz i reszta to różne typy danych, co może być powodem, dla którego Microsoft nie zaimplementował tego bezpośrednio.

Potrzebuję znaleźć skuteczny sposób obliczenia tego bez pętli. Normalnie nie byłbym przeciwny krótkiej pętli, ale te TimeSpany mogą się znacznie różnić. Im większa wykładnicza różnica między TimeSpans, tym większy iloraz. Im większy iloraz, tym więcej powtórzeń będzie musiało wykonać "pętla dzielenia". Jest to zależność, której nie mogę dopuścić w tej części mojej aplikacji.

Czy mają Państwo jakieś pomysły?

+0

Odpowiedź była tak rażąco prosta. Czuję się jak dunce, haha. Dziękuję! – Giffyguy

+1

Po udzieleniu odpowiedzi wszystko wygląda prosto. –

Odpowiedz

23

mnożenia jest łatwe:

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

Podobnie A/B:

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

i A% B:

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

Demonstracja:

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

wyjściowa:

00:07:30 
4.5 
00:00:10 
+0

czy nie stworzy to mnóstwa przedmiotów czekających na wywóz śmieci? Czy śledzenie czasu za pomocą milisekund lub kleszczy dłużej nie byłoby lepsze? – ADB

+6

TimeSpan jest strukturą i dlatego nie będzie wypalania GC. – user7116

4

Jeśli możesz przekonwertować z przedziału czasowego na liczbę sekund, którą reprezentuje, możesz zmienić te wartości, a następnie dokonać konwersji z powrotem.

5

Byłoby coś

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

daje wynik chcesz? Czy Kleszcze będą właściwą jednostką do wykonania pracy? Być może musisz przekonwertować rozpiętość na sekundy lub milisekundy lub coś takiego. Nie wiem, co to jest twoja aplikacja.

3

I nie byłoby to zrobić bezpośrednio z obiektem zakresu czasu, ale wykorzystać zdolność kleszcze.

Coś takiego.

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

Można skondensować, to w 1 kroku, ale zrobiłem to, aby zilustrować. Ułatwia i ułatwia wykonywanie dowolnych operacji matematycznych.

1

Najlepsze, co mogę zrobić, to użyć właściwości TotalSeconds i modulo. Są one jednak podwójne, pozwalają na wartości ułamkowe i dlatego mogą nie osiągnąć dokładnych wartości, których szukasz. Zawsze możesz uzyskać całe porcje i modulować je, ale ponieważ martwisz się szybkością, obawiam się, że może to być zbyt wolne dla operacji, która musi działać setki razy na sekundę.

Powiązane problemy