8
votes

Robin simple robin (moyenne mobile) dans C #

comme diagnostic, je souhaite afficher le nombre de cycles par seconde dans mon application. (Pensez des cadres par seconde dans un tireur de premier-personne.)

Mais je ne veux pas afficher la valeur la plus récente, ni la moyenne depuis le lancement. Ce que je veux calculer, c'est la moyenne des dernières valeurs x.

Ma question est que je suppose, je suppose que la meilleure façon de stocker ces valeurs. Ma première pensée était de créer une matrice de taille fixe, chaque nouvelle valeur pousserait la plus ancienne. Est-ce la meilleure façon de le faire? Si oui, comment puis-je le mettre en œuvre?

EDIT: Voici la classe I écrue: RRQUEUE . Il hérite de la file d'attente, mais applique la capacité et les détresements si nécessaire.

edit 2: Pastebin est si PASSÉ. Maintenant, sur un repo github .


0 commentaires

5 Réponses :


16
votes

L'option la plus simple pour cela est probablement d'utiliser un Queue , car cela fournit le comportement premier dans le premier en premier. Juste Enqueue () Vos articles et quand vous avez plus de x articles , Dequue () Le (s) article (s) supplémentaire (s).


7 commentaires

Aurais-je à copier sur un tableau pour obtenir la moyenne de toutes les valeurs?


@TOM: Non, la file d'attente générique .NET est implémente ienumerable afin que vous puissiez simplement énumérer sur les éléments pour calculer votre moyenne.


Si vous utilisez .NET 4.0 (éventuellement 3.5), vous devriez pouvoir simplement appeler le .sum () et .Count () extension méthodes directement sur la file d'attente. Si vous utilisez beaucoup cet idiome, il est trivial de créer un .Avoir () méthode d'extension vous-même.


@drHarris: la méthode moyenne <> () LINQ est une méthode moyenne de la plupart des types. Appelez-le directement: @Tom: juste faire: double moyenne = myQueue.avery (); // Si vous utilisez la file d'attente


Mon mauvais sur ça. Pour une raison quelconque, la moyenne ne se présente pas dans mon intellisense mais me permet de l'utiliser sans erreur. Maintenant c'est un nouveau.


@DRHARRIS: Il n'est pas implémenté pour iEnumerable , mais plutôt iénumerable - car il a besoin d'un type spécifique à calculer. C'est peut-être la raison pour laquelle vous ne le voyez pas ...



1
votes

Si vous avez besoin de la mise en œuvre la plus rapide, alors oui, une matrice de taille fixe () avec un compte séparé serait la plus rapide.


0 commentaires

0
votes

Vous devez jeter un oeil à la surveillance des performances intégrée à Windows: ré.

MSDN

L'API se sentira un peu bonsky si vous ne l'avez pas joué auparavant, mais c'est rapide, puissant, extensible et il fait un travail rapide d'obtenir des résultats utilisables.


1 commentaires

Merci Aaron. On a l'air intéressant, mais peut-être surkill pour ce dont j'ai besoin.



3
votes

Utilisez éventuellement un filtre:

moyenne = 0,9 * moyenne + 0,1 * valeur où 'valeur' ​​est la mesure la plus récente

varie avec le 0,9 et 0,1 (tant que la somme de ces deux est 1)

Ce n'est pas exactement une moyenne, mais cela filtre les pointes, les transitoires, etc., mais ne nécessite pas de réseaux pour le stockage.

salutations, Karel


1 commentaires

Pour les applications où l'exactitude mathématique formelle n'est pas nécessaire, mais plutôt un comportement de lissage souhaité, cette idée est sûre de jeter un coup d'œil!



0
votes

Ma mise en œuvre:

private RoundRobinAverage avg = new RoundRobinAverage(10);\
...
var average = avg.Calc(123);


0 commentaires