11
votes

Comment puis-je obtenir une opération de module avec des valeurs système? Système, sans boucle?

Je suis dans une partie très sensible à la performance de mon code (C # / WPF) et je dois effectuer une opération de module entre deux valeurs System.Timpan de la manière la plus rapide possible.

Ce code va courir des milliers de fois par seconde et je préférerais beaucoup éviter d'utiliser un calcul manuel de boucle - à tout prix.

L'idée d'un module entre deux fois peut sembler un peu bizarre, alors laissez-moi expliquer -
Disons que nous avons
Timespan A = 1 minute 30 secondes
Timespan B = 20 secondes

Voici une liste d'opérations courantes et de leurs résultats raisonnables:

a + b = (Timespan) 1 minute 50 secondes

A - B = (Timespan) 1 minute 10 secondes

a * b = aucune façon raisonnable de calculer
Nous devrions Devrait être capable de Multiplier un tempier par un entier. A * 5 = (Timespan) 7 minutes 30 secondes
Microsoft n'a pas mis en œuvre la multiplication entre Timespans et entiers.

a / b = (int) 4 ou (double) 4.5
Cette opération n'est pas implémentée directement dans le cadre .NET, mais cela a un sens parfait.
Il y a 4,5 b en A. (4.5 * 20 = 90)

A% B = (Timespan) 10 secondes
Compte tenu de la division Timespan raisonnable, le module Timespan devrait être assez simple.
A / B Vraiment Equals (int) 4 reste (Timespan) 10 secondes. Le quotient et le reste sont des types de données différents, ce qui peut en fait être la raison pour laquelle Microsoft n'a pas mis en œuvre cela directement.

J'ai besoin de trouver un moyen efficace de calculer cela sans boucle. Normalement, je ne serais pas opposé à une courte boucle, mais ces États-Unis pourraient grandement différer. Plus la différence exponentielle est plus grande entre les Timespans, plus le quotient est grand. Plus le quotient est grand, plus une itérations une "boucle de division" devra exécuter. Ceci est une dépendance que je ne peux pas autoriser dans cette partie de mon application.

a tellement d'idées?


2 commentaires

La réponse était si flagrante simple. Je me sens comme une dunce, haha. Merci beaucoup!


Tout semble simple une fois que vous avez la réponse.


5 Réponses :


4
votes

Si vous pouvez convertir à partir d'une durée d'entrée au nombre de secondes, vous pouvez modifier ces valeurs, puis convertir.


0 commentaires

6
votes

quelque chose comme xxx

vous donne le résultat que vous voulez? Les tiques seront-elles la bonne unité pour faire le travail? Peut-être que vous auriez besoin de convertir la portée en secondes ou de millisecondes ou quelque chose. Je ne sais pas quelle est votre application pour cela.


0 commentaires

27
votes

Multiplication est facile:

00:07:30
4.5
00:00:10


2 commentaires

Cela ne créerait-il pas une tonne d'objets en attente d'une élimination des ordures? Ne garderait pas la trace du temps en utilisant des millisecondes ou des tiques aussi longtemps être mieux à la fin?


Timespan est une structure et ne va donc pas brûler le GC.



3
votes

Je ne ferais pas cela directement avec l'objet Timespan, mais utilisez la capacité des tiques.

quelque chose comme ça. P>

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


0 commentaires

1
votes

Le mieux que je puisse penser, c'est utiliser la propriété TotaSeconds et le modulo. Cependant, ils sont doubles, permettent des valeurs fractionnaires et donc, peut ne pas atteindre les valeurs exactes que vous recherchez. Vous pouvez toujours obtenir toutes les portions et les modulo, mais comme vous êtes inquiet de la vitesse, je crains que cela ne soit trop lent pour une opération qui doit courir des centaines de fois une seconde.


0 commentaires