Skip to content

Profiling Code with the Profiler Class

The Profiler class in the utilities module is a powerful tool for measuring the execution time of code. It is particularly useful for identifying performance bottlenecks and optimizing real-time applications.

This tutorial walks you through the key features of the Profiler class and explains the examples provided in the profiling_code.py example script.

Key Features of the Profiler

The Profiler class supports four main usage patterns:

  1. Tic-Toc Timing: Measure the duration of specific code blocks that are wrapped in Tic() and Toc() commands.
  2. Expression Profiling: Profile the execution time of an expression by passing it to the profiler wrapped in a lambda function.
  3. Decorator: Automatically profile a function by decorating it.
  4. Context Manager: Use the profiler as a context manager to measure the execution time of a block of code.

Example 1: Tic-Toc Timing

The tic and toc methods allow you to measure the duration of specific code blocks.

def example_tic_toc():
    """
    Example demonstrating the use of tic and toc for profiling.
    """
    profiler = Profiler("tic_toc_example")
    profiler.tic()
    time.sleep(0.1)  # Simulate some work
    duration = profiler.toc()
    print(f"Duration of operation: {duration:.3f} seconds")

Explanation

  • tic(): Starts the timer.
  • toc(): Stops the timer and returns the elapsed time.
  • This pattern is useful for profiling specific sections of code.

Example 2: Profiling an Expression with a Lambda

The profile method allows you to measure the execution time of an expression or a small block of code by passing it as a lambda function.

def example_lambda():
    """
    Example demonstrating the use of the Profiler with a lambda function.
    """
    profiler = Profiler("lambda_example")
    for _ in range(5):
        profiler.profile(lambda: time.sleep(0.05))  # Simulate some work

    print(f"Total runs: {profiler.N}, Total time: {profiler.agg:.3f} seconds")

Explanation

  • profile(func): Measures the execution time of the provided function or expression.
  • N: The number of times the profiler has been used.
  • agg: The total time spent in all profiled expressions.

This pattern is particularly useful for profiling small, self-contained expressions or blocks of code without needing to define a separate function. For example, you can use it to measure the time taken by a single line of code or a quick computation.

Example 3: Using the Profiler as a Decorator

The decorate method allows you to profile a function by simply adding a decorator.

def example_decorator():
    """
    Example demonstrating the use of the Profiler as a decorator.
    """
    profiler = Profiler("decorator_example")

    @profiler.decorate
    def simulated_work():
        time.sleep(0.05)  # Simulate some work

    for _ in range(5):
        simulated_work()

    print(f"Total runs: {profiler.N}, Total time: {profiler.agg:.3f} seconds")

Explanation

  • @profiler.decorate: Automatically profiles the decorated function.
  • This pattern is useful for profiling functions without modifying their code.

Example 4: Using the Profiler as a Context Manager

The Profiler class can also be used as a context manager to measure the execution time of a block of code.

def example_context():
    """
    Example demonstrating the use of the Profiler with a context manager.
    """
    profiler = Profiler("context_example")
    with profiler:
        time.sleep(0.1)  # Simulate some work
    with profiler:
        time.sleep(0.2)  # Simulate some more work

    print(f"Total runs: {profiler.N}, Total time: {profiler.agg:.3f} seconds")
    print(f"Average time per run: {profiler.agg / profiler.N:.3f} seconds")
    print(f"Variance: {profiler.aggvar:.3f}")

Explanation

  • with profiler: Uses the profiler instance to measure the execution time of the code inside the with block.
  • N: The number of times the profiler has been used.
  • agg: The total time spent in all profiled blocks.

This pattern provides an alternative to the tic() toc() usage that may produce cleaner code.

Summary

The Profiler class provides flexible tools for measuring execution time in real-time applications. Whether you need to profile specific code blocks, repeated function calls, or entire functions, the Profiler class has you covered.

If you have any questions or need further assistance, please post on the Open Source Leg community forum.