Calculer le nombre de messages par seconde dans une fenêtre mobile?
J'ai des messages venant dans mon programme avec milliseconde (n'importe où à partir de zéro à quelques centaines de messages d'une milliseconde).
J'aimerais en faire une analyse. Plus précisément, je veux conserver plusieurs rouler les fenêtres du nombre de messages, mis à jour que les messages arrivent. Par exemple,
- nombre de messages dans la dernière seconde
- nombre de messages dans la dernière minute
- nombre de messages dans la dernière demie-heure divisé par nombre de messages dans la dernière heure
Je ne peux pas simplement de maintenir un décompte simple comme "1,017 messages dans la dernière seconde"car je ne sais pas quand un message est vieux de plus de 1 seconde et, par conséquent, ne devrait plus être dans le comte...
J'ai pensé à maintenir une file d'attente de tous les messages, à la recherche pour le dernier message datant de plus d'une seconde, et déduire le comte de l'index. Cependant, il semble que ce serait trop lent, et mange beaucoup de mémoire.
Que puis-je faire pour garder une trace de ces comptages dans mon programme pour que je puisse efficacement ces valeurs en temps réel?
source d'informationauteur Rudiger
Vous devez vous connecter pour publier un commentaire.
C'est plus facile est gérée par un tampon cyclique.
Un tampon cyclique a un nombre fixe d'éléments, et un pointeur vers elle. Vous pouvez ajouter un élément de la mémoire tampon, et quand vous le faites, vous incrémenter le pointeur sur l'élément suivant. Si vous avez passé le tampon de longueur fixe de commencer depuis le début. C'est un espace et le temps moyen efficace de stocker des "dernier N" éléments.
Maintenant, dans votre cas, vous pouvez avoir un tampon cyclique de 1 000 compteurs, chacun comptant le nombre de messages pendant une milliseconde. L'ajout de tous les 1 000 compteurs vous donne le nombre total au cours de la dernière seconde. Bien sûr, vous pouvez optimiser la production de rapports partie par progressivement mise à jour le comte, c'est à dire déduire de l'compter le nombre d'écraser lorsque vous insérez puis ajouter le nouveau numéro.
Vous pouvez alors avoir une autre tampon cyclique qui dispose de 60 emplacements et compte le nombre total de messages dans l'ensemble, les secondes; une fois par seconde, vous prenez le nombre total de l'ordre de la milliseconde tampon et écrire le comte le tampon ayant une résolution de secondes, etc.
Ici C comme pseudo:
Vous voulez lissage exponentielautrement connu comme une exponentielle de moyenne mobile pondérée. Prendre un EWMA du temps depuis le dernier message est arrivé, et puis la diviser le temps en une seconde. Vous pouvez exécuter plusieurs de ces différents poids pour couvrir efficacement les intervalles de temps plus longues. Effectivement, vous êtes à l'aide d'un infiniment long de la fenêtre, de sorte que vous n'avez pas à se soucier de l'expiration de données; la réduction de poids de le faire pour vous.
Pour la dernière millisecord, gardez le comte. Lorsque le millisecord tranche va à la prochaine, réinitialiser le comte et ajouter le comte à une milliseconde de roulement tableau tampon. Si vous gardez ce cumulative, vous pouvez extraire le nombre de messages /seconde avec un montant fixe de la mémoire.
Lors de l'une de 0,1 seconde tranche (ou une autre petite valeur de près de 1 minute) est fait, la somme jusqu'à la dernière 0,1*1000 articles des rolling tableau tampon et le placer que dans le prochain roulement de la mémoire tampon. De cette façon, vous kan garder le millisecord de roulement de la mémoire tampon de petite taille (1000 articles pour 1s max de recherche) et de la mémoire tampon pour la recherche de la minute aussi (600 points).
Vous pouvez faire la prochaine astuce pour l'ensemble du procès-verbal de 0,1 minutes d'intervalle. Toutes les questions posées peuvent être interrogé par la somme (ou lors de l'utilisation cumulée , soustrayant deux valeurs) quelques entiers.
Le seul inconvénient est que le dernier de la sec de la valeur wil changer tous les ms et la valeur de minute seulement tous les 0,1 secand la valeur de l'heure (et dérivés, à l' % dans la dernière 1/2 heure) tous les 0,1 minute. Mais au moins vous gardez votre utilisation de la mémoire à la baie.
Votre roulant fenêtre d'affichage ne pouvez mettre à jour de manière rapide, permet de dire que vous voulez le mettre à jour à 10 fois par seconde, donc pour 1 seconde vaut la peine de données, vous avez besoin de 10 valeurs. Chaque valeur doit contenir le nombre de messages qui ont montré que 1/10 de seconde. Appelons ces valeurs bacs, chaque bin est titulaire d'1/10 de seconde vaut de données. Toutes les 100 millisecondes, l'un des bacs est rejeté et un nouveau bac est réglé sur le nombre de messages qui ont montrer jusqu'à 100 millisecondes.
Vous auriez besoin d'un tableau de 36K bacs à tenir une heure vaut la peine d'informations sur votre fréquence de message si vous avez envie de conserver une précision de 1/10 de seconde pour l'heure entière. Mais cela semble exagéré.
Mais je pense qu'il serait plus raisonnable d'avoir la précision baisse à mesure que le temps inteval devient plus grand.
Peut-être que vous gardez à 1 seconde vaut la peine de données exactes à 100 millisecondes, à 1 minutes de la peine de données précises pour le deuxième, 1 heure vaut la peine de données exacte à la minute près, et ainsi de suite.
Une meilleure idée serait de maintenir une liste de messages, l'ajout de nouveaux messages à la tête (avec un timestamp), et sautant de la queue de leur expiration. Ou même pas de pop - gardez juste un pointeur vers le message le plus ancien qui est arrivé dans les délais voulus, et avance vers la tête lorsque que le message arrive à expiration (ce qui vous permet de garder une trace de multiplier les délais avec une liste).
On peut calculer le comte, si nécessaire, en marche de la queue à la tête, ou tout simplement stocker le comte séparément, en augmentant à chaque fois que vous ajoutez une valeur à la tête, et décrémenter à chaque fois que vous l'avance la queue.