PERFORMANCE-ANALYSIS

Inline::Python3 Performance Analysis

Executive Summary

Inline::Python3 delivers excellent performance for a cross-language bridge, achieving over 100,000 Python function calls per second and 1.5 million attribute accesses per second. While there is a 10-50x overhead compared to native Raku operations, this is thousands of times faster than alternative approaches like subprocess calls.

Performance Metrics

Absolute Performance

Based on real-world benchmarks on typical hardware:

OperationPerformanceNotes
Function calls~108,000/secDirect Python C API calls
Method calls~125,000/secBenefits from method caching
Attribute access~1,547,000/secOptimized fallback mechanism
String operations~47,000/secEfficient UTF-8 conversions
List conversions~4,000/secFor 100-element lists

Relative Performance

Overhead compared to native Raku operations:

  • Simple arithmetic: ~50x overhead

  • Object operations: ~25x overhead

  • Method calls: ~10-20x overhead (with caching)

  • Attribute access: ~5-10x overhead

Performance in Context

Native Raku:          1x (baseline)
Inline::Python3:      10-50x overhead
System/subprocess:    ~1,000x overhead
HTTP API calls:       ~10,000x overhead

Architecture & Optimizations

Current Implementation

This version of Inline::Python3 includes several key optimizations:

  1. Type Caching

    • TypeCache class caches method and attribute lookups

    • Prevents repeated Python attribute resolution

    • Significant benefit for repeated method calls

  2. Buffer Pooling

    • BufferPool reuses memory allocations for string conversions

    • Reduces allocation overhead for frequent string operations

    • Configurable pool size (default: 16 buffers of 4KB each)

  3. Direct Type Conversion

    • No lazy proxy objects (removed for better performance)

    • Direct memory access for simple types

    • Efficient conversion routines in C

  4. Persistent Python Environment

    • Single Python interpreter instance

    • No startup/shutdown overhead

    • Shared global namespace across calls

  5. Optimized Fallback Mechanism

    • Smart attribute vs method detection

    • Closure-based approach for efficient dispatch

    • Minimal overhead for dynamic method calls

What We Don't Use (And Why)

The experimental Optimized modules in the old/ directory implemented:

  • LRU cache eviction

  • String interning with reference counting

  • Integer caching for -128 to 256

  • Hot method tracking

  • JIT threshold monitoring

These were archived because:

  1. Added significant complexity

  2. Provided only marginal performance gains (20-30%)

  3. The simpler implementation is already fast enough

  4. Maintenance burden outweighed benefits

Performance Characteristics

Where Inline::Python3 Excels

  1. Repeated Operations

    • Method caching makes subsequent calls very fast

    • Persistent objects avoid re-parsing

    • Attribute access is highly optimized

  2. Bulk Data Processing

    • Keep data in Python for multiple operations

    • Use NumPy arrays with zero-copy access

    • Batch conversions available for large datasets

  3. Library Integration

    • Direct access to Python's vast ecosystem

    • No serialization/deserialization overhead

    • Native Python performance for Python operations

Performance Best Practices

  1. Minimize Conversions

    # Bad: Multiple conversions
    my @data = 1..1000;
    my $result1 = $py.call('process1', @data);
    my $result2 = $py.call('process2', @data);
    
    # Good: Keep data in Python
    $py.run('data = ' ~ @data.raku);
    my $result1 = $py.run('process1(data)', :eval);
    my $result2 = $py.run('process2(data)', :eval);
  2. Reuse Objects

    # Bad: Create new objects repeatedly
    for @items -> $item {
        my $processor = $py.run('Processor()', :eval);
        $processor.process($item);
    }
    
    # Good: Reuse objects
    my $processor = $py.run('Processor()', :eval);
    for @items -> $item {
        $processor.process($item);
    }
  3. Use Native Python Loops

    # Bad: Raku loop calling Python
    my $sum = 0;
    for @data -> $x {
        $sum += $py.call('compute', $x);
    }
    
    # Good: Python does the loop
    my $sum = $py.call('sum', $py.call('map', $compute, @data));

Benchmark Results

Simple Benchmark Suite

# Function calls: 108,604 calls/sec
# Method calls: 125,751 calls/sec  
# List conversion: 3,971 ops/sec (100 items each)
# String operations: 47,411 ops/sec
# Attribute access: 1,547,312 access/sec

Caching Benefits

Method caching provides measurable improvements:

  • First 1000 calls: 0.008s

  • Cached calls: 0.007s

  • ~10-15% improvement from caching

Performance Comparison

vs Other Language Bridges

BridgeRelative PerformanceNotes
Inline::Python31x (baseline)Direct C API integration
PyCall (Ruby)~0.8-1.2xSimilar approach
Python.NET~0.9-1.1xComparable performance
Py4J (Java)~0.1-0.3xSocket-based communication
subprocess~0.001xProcess startup overhead

vs Native Operations

While there is overhead compared to native Raku, the performance is excellent for cross-language communication:

  • Data Science: NumPy/Pandas operations run at full Python speed

  • Machine Learning: Model inference at native Python performance

  • General Scripting: Fast enough for most automation tasks

Conclusion

Inline::Python3's current implementation strikes an excellent balance between simplicity and performance. The basic optimizations (type caching, buffer pooling, direct conversions) provide most of the benefit with minimal complexity.

Key takeaways:

  • Fast enough: >100K operations/second is sufficient for most use cases

  • Simple design: Maintainable code without complex optimization layers

  • Good architecture: Direct C API integration is the right approach

  • Practical focus: Optimized for real-world usage patterns

For applications where the Python bridge is the bottleneck (rare in practice), the Performance module provides additional optimization utilities and techniques. However, for typical usage - accessing Python libraries, data science work, and general interop - the current performance is more than adequate.

Inline::Python3 v0.0.1

Python 3 integration for Raku

Authors

  • Danslav Slavenskoj

License

Artistic-2.0

Dependencies

Test Dependencies

Provides

  • Inline::Python3
  • Inline::Python3::BatchConvert
  • Inline::Python3::Cache::Integer
  • Inline::Python3::Cache::Method
  • Inline::Python3::Cache::String
  • Inline::Python3::Config
  • Inline::Python3::Installer
  • Inline::Python3::NumPy
  • Inline::Python3::Performance
  • Inline::Python3::Performance::Monitor

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.