Fundamentals 9 min read

Benchmarking Python 3.11 Performance Against C++ Using Monte Carlo Pi Estimation

This article benchmarks Python 3.11's speed with a Monte Carlo Pi estimation script, compares it to earlier Python releases and a C++ implementation, shows Docker‑based testing methodology, presents performance results, and extrapolates when Python might surpass C++ in execution time.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Benchmarking Python 3.11 Performance Against C++ Using Monte Carlo Pi Estimation

Python is one of the most popular languages for data science and machine learning, often praised for its extensive libraries and ease of integration. Recent versions, especially 3.11, claim significant speed improvements.

The article reproduces a performance test originally conducted by an external researcher, using a Monte Carlo method to estimate π. The algorithm randomly generates points inside a square and counts how many fall within an inscribed circle, then approximates π from the ratio.

A parametrized Python script (using argparse ) implements the test and measures execution time. The core functions are:

def estimate_pi(n_points: int, show_estimate: bool) -> None:
    """Simple Monte Carlo Pi estimation calculation.
    Parameters
    ----------
    n_points : int
        Number of random points used for estimation.
    show_estimate : bool
        Whether to print the estimated value.
    """
    within_circle = 0
    for _ in range(n_points):
        x, y = (random.uniform(-1, 1) for _ in range(2))
        if x**2 + y**2 <= 1:
            within_circle += 1
    pi_estimate = 4 * within_circle / n_points
    if show_estimate:
        print("Final Estimation of Pi=", pi_estimate)


def run_test(n_points: int, n_repeats: int, only_time: bool) -> None:
    """Perform the tests and measure required time.
    Parameters
    ----------
    n_points : int
        Number of random numbers used for estimation.
    n_repeats : int
        Number of times the test is repeated.
    only_time : bool
        If True, only print the timing information.
    """
    start_time = time.time()
    for _ in range(n_repeats):
        estimate_pi(n_points, only_time)
    if only_time:
        print(f"{(time.time() - start_time) / n_repeats:.4f}")
    else:
        print(f"Estimating pi took {(time.time() - start_time) / n_repeats:.4f} seconds per run.")

Testing multiple Python versions is performed inside Docker containers to ensure a consistent environment. The Docker command used is:

docker run -it --rm \
  -v $PWD/your_script.py:/your_script.py \
  python:3.11-rc-slim \
  python /your_script.py

Results for seven Python releases show that Python 3.11 averages 6.46 seconds per run, roughly 37 % faster than 3.10. A visual chart (omitted) illustrates the performance trend.

For comparison, a C++ implementation using chrono for timing is provided:

#include <stdlib.h>
#include <stdio.h>
#include <chrono>
#include <array>
#define N_POINTS 10000000
#define N_REPEATS 10

float estimate_pi(int n_points) {
    double x, y, radius_squared, pi;
    int within_circle = 0;
    for (int i = 0; i < n_points; ++i) {
        x = (double)rand() / RAND_MAX;
        y = (double)rand() / RAND_MAX;
        radius_squared = x*x + y*y;
        if (radius_squared <= 1) ++within_circle;
    }
    pi = (double)within_circle / n_points * 4;
    return pi;
}

int main() {
    double avg_time = 0;
    srand(42);
    for (int i = 0; i < N_REPEATS; ++i) {
        auto begin = std::chrono::high_resolution_clock::now();
        double pi = estimate_pi(N_POINTS);
        auto end = std::chrono::high_resolution_clock::now();
        auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
        avg_time += elapsed.count() * 1e-9;
        printf("Pi is approximately %g and took %.5f seconds to calculate.\n", pi, elapsed.count() * 1e-9);
    }
    printf("\nEach loop took on average %.5f seconds to calculate.\n", avg_time / N_REPEATS);
}

The C++ version completes a single loop in about 0.257 seconds, dramatically faster than any Python release. A line representing this result is added to the earlier performance chart.

Assuming the observed speed‑up trend continues, the article extrapolates that Python 3.14 could surpass C++ in this specific benchmark, predicting a negative runtime difference (i.e., Python finishing before C++).

The author notes that the analysis is speculative, the code is publicly available, and the conclusions are based on the presented data.

performanceDockerPythonC++Benchmarkingmonte carlospeed
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.