【Cherno的C++视频】Visual benchmarking in C++

#include <iostream>
#include <string>
#include <chrono>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <thread>

// how to measure performance visually.
// chrome://tracing-> it loads in a json file and you'll see.

struct ProfileResult
{
	std::string Name;
	long long Start, End;
	uint32_t ThreadID;
};

struct InstrumentationSession
{
	std::string Name;
};

// Formatting a json file and write it out into a file.
class Instrumentor
{
private:
	InstrumentationSession* m_CurrentSession;
	std::ofstream m_OutputStream;
	int m_ProfileCount;
public:
	Instrumentor()
		: m_CurrentSession(nullptr), m_ProfileCount(0)
	{
	}

	void BeginSession(const std::string& name, const std::string& filepath = "testFile/VisualBenchmarkingResults.json")
	{
		m_OutputStream.open(filepath);
		WriteHeader();
		m_CurrentSession = new InstrumentationSession{ name };
	}

	void EndSession(void)
	{
		WriteFooter();
		m_OutputStream.close();
		delete m_CurrentSession;
		m_CurrentSession = nullptr;
		m_ProfileCount = 0;
	}
	// it's the meat of this entire class.
	void WriteProfile(const ProfileResult& result)
	{
		if (m_ProfileCount++ > 0)
		{
			m_OutputStream << ",";
		}

		std::string name = result.Name;
		std::replace(name.begin(), name.end(), '"', '\'');

		m_OutputStream << "{";
		m_OutputStream << "\"cat\":\"function\",";
		m_OutputStream << "\"duration\":" << (result.End - result.Start) << ',';
		m_OutputStream << "\"name\":\"" << name << "\",";
		m_OutputStream << "\"ph\":\"X\",";
		m_OutputStream << "\"pid\":0,";
		m_OutputStream << "\"tid\":" << result.ThreadID << ",";
		m_OutputStream << "\"ts\":" << result.Start;
		m_OutputStream << "}";
		m_OutputStream.flush();
	}

	void WriteHeader(void)
	{
		m_OutputStream << "{\"otherData\": {},\"traceEvents\":[";
		m_OutputStream.flush();
	}

	void WriteFooter(void)
	{
		m_OutputStream << "]}";
		m_OutputStream.flush();
	}

	static Instrumentor& Get(void)
	{
		static Instrumentor* instance = new Instrumentor();
		return *instance;
	}
};

class InstrumentationTimer
{
public:
	InstrumentationTimer(const char* name)
		: m_Name(name), m_Stopped(false)
	{
		m_StartTimepoint = std::chrono::high_resolution_clock::now();
	}

	~InstrumentationTimer(void)
	{
		if (!m_Stopped)
		{
			Stop();
		}
	}
	
	void Stop(void)
	{
		auto endTimepoint = std::chrono::high_resolution_clock::now();
		long long start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();
		auto end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimepoint).time_since_epoch().count();
		//std::cout << m_Name << ": " << (end - start) << " us\n";
		uint32_t threadID = std::hash<std::thread::id>{} (std::this_thread::get_id());
		Instrumentor::Get().WriteProfile({m_Name, start, end, threadID});
		m_Stopped = true;
	}
private:
	const char* m_Name;
	std::chrono::time_point<std::chrono::steady_clock> m_StartTimepoint;
	bool m_Stopped;
};

#define PROFILING 1
#if PROFILING
#define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name)
#define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__)
#else
#define PROFILE_SCOPE(name)
#endif

namespace Benchmark {
	void PrintFunction(int value)
	{
		PROFILE_FUNCTION();
		for (int i = 0; i < 1000; i++)
		{
			std::cout << "Hello World #" << i + value << std::endl;
		}
	}

	void PrintFunction(void)
	{
		PROFILE_FUNCTION();
		for (int i = 0; i < 1000; i++)
		{
			std::cout << "Hello World #" << sqrt(i) << std::endl;
		}
	}

	void RunBenchmarks(void)
	{
		PROFILE_FUNCTION();
		std::cout << "Running Benchmarks...\n";
		PrintFunction(2);
		std::thread a([]() {PrintFunction(); });

		a.join();
	}
}

int main(void)
{
	Instrumentor::Get().BeginSession("Profile");
	Benchmark::RunBenchmarks();
	Instrumentor::Get().EndSession();

	std::cin.get();
}

VisualBenchmarkingInCpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值