Created
September 6, 2023 06:48
-
-
Save happyme531/3dba11f3c53006aa1817f0a89aceb5fe to your computer and use it in GitHub Desktop.
Handy FPS or whatever counter class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Author: hallo1, 2023-09-06 | |
| // Description: Simple FPS or whatever counter | |
| #pragma once | |
| #include <chrono> | |
| #include <iostream> | |
| #include <string> | |
| class FPSCounter { | |
| private: | |
| float avgMsPerFrame = 0; | |
| float varMsPerFrame = 0; | |
| int currentSampleCount = 0; | |
| std::chrono::time_point<std::chrono::steady_clock> lastTime = | |
| std::chrono::steady_clock::now(); | |
| std::chrono::milliseconds logInterval = std::chrono::milliseconds(1000); | |
| std::chrono::time_point<std::chrono::steady_clock> lastLog = | |
| std::chrono::steady_clock::now(); | |
| std::ostream &out; | |
| std::string name; | |
| public: | |
| FPSCounter( | |
| std::string name = "FPS", | |
| std::chrono::milliseconds logInterval = std::chrono::milliseconds(1000), | |
| std::ostream &out = std::cout) | |
| : name(name), logInterval(logInterval), out(out) {} | |
| void start() { lastTime = std::chrono::steady_clock::now(); } | |
| void end() { | |
| auto now = std::chrono::steady_clock::now(); | |
| auto ms = | |
| std::chrono::duration_cast<std::chrono::milliseconds>(now - lastTime) | |
| .count(); | |
| currentSampleCount++; | |
| avgMsPerFrame += (ms - avgMsPerFrame) / currentSampleCount; | |
| // Welford's algorithm | |
| varMsPerFrame = (varMsPerFrame * (currentSampleCount - 1) + | |
| (ms - avgMsPerFrame) * (ms - avgMsPerFrame)) / | |
| currentSampleCount; | |
| auto intervalMs = | |
| std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLog) | |
| .count(); | |
| if (intervalMs > logInterval.count()) { | |
| // Sampling itps, calculated by the number of samples divided by the time | |
| float sampling_itps = | |
| (float)currentSampleCount / | |
| std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLog) | |
| .count() * | |
| 1000; | |
| // Timing itps, calculated by the average time per iteration | |
| float timing_itps = 1000.0 / avgMsPerFrame; | |
| float proportionPercentage = sampling_itps / timing_itps * 100; | |
| out << std::setprecision(2) << std::fixed; | |
| out << name << ": itps=" << sampling_itps | |
| << ", timing_itps=" << timing_itps << ", avg=" << avgMsPerFrame | |
| << "ms, stddev=" << sqrt(varMsPerFrame) | |
| << "ms, proportion=" << proportionPercentage | |
| << "%, samples=" << currentSampleCount << std::endl; | |
| avgMsPerFrame = 0; | |
| varMsPerFrame = 0; | |
| currentSampleCount = 0; | |
| lastLog = now; | |
| } | |
| } | |
| }; | |
| // int main() { | |
| // FPSCounter counter("test", std::chrono::milliseconds(1000)); | |
| // std::random_device rd; | |
| // std::mt19937 gen(rd()); | |
| // std::normal_distribution<> d1(30, 5); | |
| // std::normal_distribution<> d2(60, 5); | |
| // while (true) { | |
| // counter.start(); | |
| // //Some stressful work | |
| // std::this_thread::sleep_for(std::chrono::milliseconds((int)d1(gen))); | |
| // counter.end(); | |
| // //Maybe some other work | |
| // std::this_thread::sleep_for(std::chrono::milliseconds((int)d2(gen))); | |
| // } | |
| // } | |
| // test: itps=10.16, timing_itps=25.82, avg=38.73ms, stddev=8.85ms, proportion=39.34%, samples=11 | |
| // test: itps=9.62, timing_itps=28.99, avg=34.50ms, stddev=5.75ms, proportion=33.17%, samples=10 | |
| // test: itps=10.24, timing_itps=30.05, avg=33.27ms, stddev=5.20ms, proportion=34.08%, samples=11 | |
| // test: itps=9.68, timing_itps=28.82, avg=34.70ms, stddev=5.58ms, proportion=33.59%, samples=10 | |
| // test: itps=9.77, timing_itps=29.24, avg=34.20ms, stddev=5.99ms, proportion=33.40%, samples=10 | |
| // test: itps=8.84, timing_itps=25.35, avg=39.44ms, stddev=7.06ms, proportion=34.87%, samples=9 | |
| // test: itps=9.35, timing_itps=25.71, avg=38.90ms, stddev=6.55ms, proportion=36.36%, samples=10 | |
| // test: itps=9.70, timing_itps=29.15, avg=34.30ms, stddev=5.84ms, proportion=33.27%, samples=10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment