Measure Python code performance before you optimize

A client last month was running a WooCommerce store with about 50,000 products, synced through a custom Python bridge. It held up fine until they grew the catalog. Then the sync script that used to finish in ten minutes started grinding away for three hours, and stock levels drifted out of sync while it ran. The client was panicking. I needed real numbers on where the time was going, the same way you would when optimizing REST API performance, before the whole system fell over.

I assumed the bottleneck was the WooCommerce REST API and spent close to two hours on request batch sizes and headers. It barely moved the number. Gut feelings about performance are usually wrong, and I was throwing darts in the dark. So I stopped guessing and went looking for data on where the clock cycles were actually going.

How to measure Python code performance with cProfile

You do not need an expensive suite to find the hot paths in Python code. The standard library ships cProfile, a deterministic profiler: it records every function call, how many times each one ran, and how long each took. Feed the output into SnakeViz and you get a visual map where the bottleneck is hard to miss.

Here is the setup I used on that sync script. I wrapped the main execution block so it writes a profile dump, which tells you far more than staring at raw logs does.

import cProfile
import pstats
import io

def bbioon_run_sync_process():
    # Imagine a complex sync logic here
    pass

# Initialize the profiler
pr = cProfile.Profile()
pr.enable()

# Execute the bridge logic
bbioon_run_sync_process()

pr.disable()

# Export stats to a file for SnakeViz
pr.dump_stats('bbioon_sync_profile.prof')

# Or just print the top 10 heavy hitters to the console
s = io.StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats('cumtime')
ps.print_stats(10)
print(s.getvalue())

Running it on the client’s script was a little embarrassing. While I was busy with the API, a nested loop was doing string concatenation for the product descriptions. The script spent about 70% of its time re-allocating memory for strings. Skip the step where you measure Python code performance and you will lose hours fixing things that were never broken.

Fixing the hot paths: vectorization and joining

Once SnakeViz drew the giant icicle bars, the fixes were obvious. I swapped the iterative string building for "".join() and moved the price calculation over to NumPy. It is the same move as when you handle WordPress performance optimization: find the heaviest query or loop and take the redundancy out of it.

import numpy as np

# THE OLD SLOW WAY (Iterative math in a loop)
def bbioon_slow_calc(data):
    results = []
    for x in data:
        results.append(x * 1.2) # Adding tax or margin
    return results

# THE FAST WAY (Vectorized with NumPy)
def bbioon_fast_calc(data_array):
    # This runs in optimized C code, bypassing the Python interpreter loop
    return data_array * 1.2

# THE STRING FIX
# Instead of: report += f"|{item}"
# Use:
# bbioon_report = "".join([f"|{i}" for i in items])

Sync time dropped from three hours to under twelve minutes. The client thought that was magic. It was a profiler pointing at the right line. Taking the time to measure Python code performance meant a couple of surgical fixes instead of refactoring the whole codebase.

What to take from this

  • Your intuition about performance is usually wrong, so treat cProfile output as the only source of truth.
  • Run the dump through SnakeViz when a table of numbers is not telling you anything.
  • Optimize only the functions eating the most cumulative time and leave the rest alone.
  • Profile again after each fix, because solving one bottleneck often exposes the next one sitting behind it.

This gets complicated fast, especially when you are bridging external data into WooCommerce. If you are tired of debugging someone else’s mess and want a site that holds up at scale, drop me a line. I have probably seen it before.

Are you still timing your code with print statements, or have you tried a real profiler?

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.