2017-10-16 3 views
6

Contexte: J'écris une application C++ 11 hautes performances, dont une partie consiste à supprimer les connexions inactives. Pour cela, je stocke un horodatage de "dernière activité" dans mon objet de connexion, que je mets à jour lorsqu'une action est effectuée. J'ai alors une minuterie qui s'exécute toutes les quelques secondes, boucle toutes les sessions, et supprime celles qui sont inactives.Quel est le moyen le plus rapide d'obtenir l'heure actuelle dans C++ 11?

Actuellement, je suis en utilisant ce code pour obtenir l'horodatage actuel:

timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count() 

Je me demande s'il y a une façon plus rapide de le faire? Par rapide, je veux dire la performance de l'horodatage lui-même, pas la résolution de l'horodatage.

La résolution n'est pas vraiment importante pour mon application spécifique, elle pourrait descendre aussi bas qu'une seconde. En outre, utc/local n'a pas d'importance, je n'utilise que l'horodatage pour le comparer à d'autres horodatages, acquis par la même méthode. Je souhaiterais le garder multi-plateforme, mais les optimisations spécifiques à la plate-forme avec compilation conditionnelle sont également les bienvenues.

+7

Pourquoi ne faites-vous pas simplement 'timestamp = system_clock :: now();'? – nwp

+5

Avez-vous * mesuré * que l'extraction d'horodatage est un goulot d'étranglement? Avez-vous examiné le code machine généré (optimisé!)? –

+0

Pour ajouter à @nwp, vous pouvez simplement vérifier que 'system_clock :: now() - timestamp

Répondre

5

Si les performances sont vraiment un problème, et que la précision ne l'est pas, il n'est pas nécessaire d'utiliser un horodatage. Plutôt simplement garder un compteur pour chaque connexion, et chaque fois que l'activité se produit pour la connexion, réinitialiser le compteur à zéro. Chaque fois que votre minuterie s'éteint, il faut incrémenter le compteur pour chaque connexion, et déconnecter toute connexion dont la valeur du compteur dépasse (N) (pour toute valeur de N que vous trouvez mieux)

+1

Et si vous ne voulez pas que la précision de la minuterie de la tâche de nettoyage ait de l'importance, demandez-lui d'enregistrer le temps écoulé depuis sa dernière exécution et d'incrémenter les compteurs de * autant *.Vous générez maintenant une approximation correcte de la solution de l'OP, et ne calculez le temps * une fois * que toutes les quelques secondes sur un thread critique non performant. – Yakk

0

Vous pouvez maintenir une variable locale de thread par thread, et ajoutez un timerfd par thread (ou vous pouvez utiliser le paramètre select/epoll timeout) pour réveiller le thread toutes les 1 millisecondes, lorsque le retour select/epoll_wait, vous appelez now() pour obtenir l'horodatage, et enregistrez l'horodatage thread variable locale.

Vous pouvez également utiliser une variable globale, par exemple, std :: atomic, et la mettre à jour lorsque vous sélectionnez/epoll (dans tous les threads). Si vous pensez toujours que c'est un goulot d'étranglement, utilisez un seul thread avec timerfd et mettez à jour l'horodatage toutes les 1 millisecondes.