Skip to content

Commit

Permalink
implement Python's FASTCALL convention even though it isn't much faster
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitmel committed Jun 14, 2021
1 parent fc33e3f commit a42c1cc
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ target/
__pycache__/
*.py[cod]
build/
.ccls-cache/
54 changes: 51 additions & 3 deletions extras/mega_tournament_ultra_fast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,58 @@
#include <Python.h>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <random>
#include <vector>

namespace mega_tournament_ultra_fast {

PyObject *run_tournament(PyObject *self, PyObject *args) {
#ifdef METH_FASTCALL
// FASTCALL doesn't make the function faster in my instance, so it is disabled
// #define mega_tournament_use_fastcall
#endif

PyObject *run_tournament(PyObject *self,
#ifdef mega_tournament_use_fastcall
PyObject *const *args, Py_ssize_t nargs
#else
PyObject *args
#endif
) {
size_t total_players = 0;
double champion_win_probability = 0;
double regular_player_win_probability = 0;

#ifdef mega_tournament_use_fastcall

const Py_ssize_t required_nargs = 3;
if (nargs != required_nargs) {
// <https://github.com/python/cpython/blob/v3.9.5/Python/getargs.c#L374-L382>
PyErr_Format(PyExc_TypeError,
"function takes exactly %d argument%s (%zd given)",
required_nargs, required_nargs == 1 ? "" : "s", nargs);
return nullptr;
}

total_players = PyLong_AsSize_t(args[0]);
if (PyErr_Occurred()) {
return nullptr;
}
champion_win_probability = PyFloat_AsDouble(args[1]);
if (PyErr_Occurred()) {
return nullptr;
}
regular_player_win_probability = PyFloat_AsDouble(args[2]);
if (PyErr_Occurred()) {
return nullptr;
}

#else
if (!PyArg_ParseTuple(args, "ldd", &total_players, &champion_win_probability,
&regular_player_win_probability)) {
return NULL;
return nullptr;
}
#endif

static thread_local bool rng_initialized = false;
static thread_local std::default_random_engine rng_engine;
Expand Down Expand Up @@ -60,8 +98,18 @@ PyObject *run_tournament(PyObject *self, PyObject *args) {
return PyLong_FromSsize_t(best_player);
}

#ifdef mega_tournament_use_fastcall
_PyCFunctionFast _run_tournament_type_assert = run_tournament;
#endif

static PyMethodDef py_methods[] = {
{"run_tournament", run_tournament, METH_VARARGS, nullptr},
{"run_tournament", (PyCFunction)run_tournament,
#ifdef mega_tournament_use_fastcall
METH_FASTCALL,
#else
METH_VARARGS,
#endif
nullptr},
{nullptr, nullptr, 0, nullptr},
};

Expand Down

0 comments on commit a42c1cc

Please sign in to comment.