Last active
September 10, 2022 06:45
-
-
Save JuanDiegoMontoya/e9a861cb35bff66655354341485f4d42 to your computer and use it in GitHub Desktop.
Fast-compiling timer class that relies on cursed and undefined behavior. Notably, the header does not include any headers itself. At the bottom should be a not-UB version that includes the necessary header.
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
#pragma once | |
class Timer | |
{ | |
public: | |
Timer(); | |
void Reset(); | |
double Elapsed_s() const; | |
Timer(const Timer& other); | |
Timer& operator=(const Timer& other); | |
private: | |
alignas(8) char mem_[8]; | |
}; |
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
#include "Timer.h" | |
#include <chrono> | |
#include <new> | |
using second_t = std::chrono::duration<double, std::ratio<1>>; | |
using myclock_t = std::chrono::steady_clock; | |
using timepoint_t = std::chrono::time_point<myclock_t>; | |
Timer::Timer() | |
{ | |
static_assert(sizeof(timepoint_t) == sizeof(mem_), "You need to change the size of the internal storage!"); | |
new(mem_) timepoint_t(myclock_t::now()); | |
} | |
void Timer::Reset() | |
{ | |
new(mem_) timepoint_t(myclock_t::now()); | |
} | |
double Timer::Elapsed_s() const | |
{ | |
// beg to your god | |
timepoint_t beg_ = *std::launder(reinterpret_cast<const timepoint_t*>(mem_)); | |
return std::chrono::duration_cast<second_t>(myclock_t::now() - beg_).count(); | |
} | |
Timer::Timer(const Timer& other) | |
{ | |
*this = other; | |
} | |
Timer& Timer::operator=(const Timer& other) | |
{ | |
if (&other == this) return *this; | |
timepoint_t beg_ = *std::launder(reinterpret_cast<const timepoint_t*>(other.mem_)); | |
new(mem_) timepoint_t(beg_); | |
return *this; | |
} |
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
#pragma once | |
#include <chrono> | |
// this timer is what you would use if you're not insane | |
class Timer | |
{ | |
using microsecond_t = std::chrono::duration<double, std::ratio<1'000'000>>; | |
using myclock_t = std::chrono::steady_clock; | |
using timepoint_t = std::chrono::time_point<myclock_t>; | |
public: | |
Timer() | |
{ | |
timepoint_ = myclock_t::now(); | |
} | |
void Reset() | |
{ | |
timepoint_ = myclock_t::now(); | |
} | |
double Elapsed_us() const | |
{ | |
timepoint_t beg_ = timepoint_; | |
return std::chrono::duration_cast<microsecond_t>(myclock_t::now() - beg_).count(); | |
} | |
private: | |
timepoint_t timepoint_; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment