Skip to content

Instantly share code, notes, and snippets.

@Techcable
Last active June 14, 2021 09:04
Show Gist options
  • Save Techcable/47ddd3750adc5b9df824b6b3986eb251 to your computer and use it in GitHub Desktop.
Save Techcable/47ddd3750adc5b9df824b6b3986eb251 to your computer and use it in GitHub Desktop.
Benchmarks bytecode compilaiton in various langauges
/*
* See github gist:
* https://gist.github.com/Techcable/47ddd3750adc5b9df824b6b3986eb251
*/
#include <string>
#include <cstdlib>
#include <optional>
#include <vector>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <Python.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
}
#include "benchmark/benchmark.h"
class MissingEnvException: public std::runtime_error {
public:
MissingEnvException(): std::runtime_error("Missing environment variable") {}
};
std::vector<std::string> parse_file_list(const char *env_name) {
const char *raw = std::getenv(env_name);
if (raw == nullptr) {
throw MissingEnvException();
}
auto s = std::string(raw);
std::vector<std::string> res {};
size_t next_comma;
size_t last_comma = 0;
while ((next_comma = s.find(",", last_comma)) != std::string::npos) {
res.push_back(s.substr(last_comma, next_comma));
last_comma = next_comma;
}
res.push_back(s.substr(last_comma, res.size()));
return res;
}
std::string load_file(std::string& file_name) {
auto in = std::ifstream(file_name);
char buffer[4096];
std::string res;
while (in.read(buffer, sizeof(buffer))) {
res.append(buffer, sizeof(buffer));
}
res.append(buffer, in.gcount());
return res;
}
class CompileBench : public benchmark::Fixture {
public:
CompileBench(const char *env_name): env_source_name(env_name) {}
virtual void setupInterpreter() = 0;
virtual void compile(std::string& text) = 0;
void SetUp(const ::benchmark::State& state) {
this->setupInterpreter();
auto v = parse_file_list(this->env_source_name);
std::vector<std::string> res;
for (auto s : v) {
res.push_back(load_file(s));
}
this->original_sources = res;
}
void compileAll() {
for (std::string& src : this->original_sources) {
this->compile(src);
}
}
private:
const char *env_source_name;
std::vector<std::string> original_sources {};
};
class PythonCompileBench : public CompileBench {
public:
PythonCompileBench(): CompileBench("PYTHON_SOURCES") {}
virtual void setupInterpreter() {
Py_Initialize();
}
virtual void compile(std::string &text) {
PyObject *res = Py_CompileString(text.c_str(), "dummy_bench.py", Py_file_input);
if (res == NULL) {
PyErr_Print();
throw std::runtime_error("Internal Python Error");
}
Py_DECREF(res);
}
};
const char *lua_string_reader(lua_State *lua, void *data, size_t *size) {
std::string *s = static_cast<std::string*>(data);
*size = s->size();
return s->data();
}
class LuaCompileBench: public CompileBench {
public:
LuaCompileBench(): CompileBench("LUA_SOURCES") {}
virtual void setupInterpreter() {
this->state = luaL_newstate();
}
virtual void compile(std::string &text) {
int res = luaL_loadbuffer(this->state, text.data(), text.size(), "dummy_bench.lua");
if (res != LUA_OK) {
throw std::runtime_error("Internal Lua error");
}
lua_pop(this->state, 1);
}
lua_State *state = nullptr;
};
BENCHMARK_F(PythonCompileBench, PythonCompileBench)(benchmark::State& st) {
for (auto _ : st) {
this->compileAll();
}
}
BENCHMARK_F(LuaCompileBench, LuaCompileBench)(benchmark::State& st) {
for (auto _ : st) {
this->compileAll();
}
}
BENCHMARK_MAIN();
@Techcable
Copy link
Author

This is actually my first C++. That's why it's so ugly 😜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment