]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111139: Optimize math.gcd(int, int) (#113887)
authorVictor Stinner <vstinner@python.org>
Wed, 10 Jan 2024 15:38:56 +0000 (16:38 +0100)
committerGitHub <noreply@github.com>
Wed, 10 Jan 2024 15:38:56 +0000 (16:38 +0100)
Add a fast-path for the common case.

Benchmark:

    python -m pyperf timeit \
        -s 'import math; gcd=math.gcd; x=2*3; y=3*5' \
        'gcd(x,y)'

Result: 1.07x faster (-3.4 ns)

    Mean +- std dev: 52.6 ns +- 4.0 ns -> 49.2 ns +- 0.4 ns: 1.07x faster

Modules/mathmodule.c

index 6cd61e9ab75424e692f8c5ba35813b07c3d95fca..2a796c1c55d2f0aa824bdc09a290f5678f1e69b3 100644 (file)
@@ -759,13 +759,17 @@ m_log10(double x)
 static PyObject *
 math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs)
 {
-    PyObject *res, *x;
-    Py_ssize_t i;
+    // Fast-path for the common case: gcd(int, int)
+    if (nargs == 2 && PyLong_CheckExact(args[0]) && PyLong_CheckExact(args[1]))
+    {
+        return _PyLong_GCD(args[0], args[1]);
+    }
 
     if (nargs == 0) {
         return PyLong_FromLong(0);
     }
-    res = PyNumber_Index(args[0]);
+
+    PyObject *res = PyNumber_Index(args[0]);
     if (res == NULL) {
         return NULL;
     }
@@ -775,8 +779,8 @@ math_gcd(PyObject *module, PyObject * const *args, Py_ssize_t nargs)
     }
 
     PyObject *one = _PyLong_GetOne();  // borrowed ref
-    for (i = 1; i < nargs; i++) {
-        x = _PyNumber_Index(args[i]);
+    for (Py_ssize_t i = 1; i < nargs; i++) {
+        PyObject *x = _PyNumber_Index(args[i]);
         if (x == NULL) {
             Py_DECREF(res);
             return NULL;