Last active
June 14, 2021 09:04
-
-
Save Techcable/47ddd3750adc5b9df824b6b3986eb251 to your computer and use it in GitHub Desktop.
Benchmarks bytecode compilaiton in various langauges
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
/* | |
* 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(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is actually my first C++. That's why it's so ugly 😜