Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Oct 28, 2025

📄 10% (0.10x) speedup for render_pdf in panel/io/mime_render.py

⏱️ Runtime : 479 microseconds 436 microseconds (best of 201 runs)

📝 Explanation and details

The optimization eliminates an unnecessary intermediate variable assignment by combining the base64 encoding operations into a single chained expression. Instead of storing value.encode('utf-8') in a data variable and then separately creating the base64_pdf variable, the optimized version directly chains base64.b64encode(value.encode('utf-8')).decode("utf-8").

This reduces the number of variable assignments from 3 to 1, eliminating the overhead of creating and storing the intermediate data and src variables. The src variable removal is particularly beneficial as it avoids creating an intermediate f-string that's only used once in the return statement.

The optimization works well across all test scenarios, showing consistent 6-12% improvements for most string inputs. It's especially effective for:

  • Basic ASCII strings (6-17% faster)
  • Long strings and bulk processing (8-12% faster)
  • Repeated operations with many unique inputs (10-12% faster)

The performance gain comes from reduced memory allocation and fewer Python bytecode operations, while maintaining identical functionality and output.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 786 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
from __future__ import annotations

import base64

# imports
import pytest  # used for our unit tests
from panel.io.mime_render import render_pdf

# unit tests

# ---------------------------
# Basic Test Cases
# ---------------------------

def test_render_pdf_basic_ascii():
    """Test with a simple ASCII string."""
    value = "Hello PDF"
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 1.92μs -> 1.81μs (6.31% faster)
    # Check that the value is base64 encoded in the output
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_basic_unicode():
    """Test with a Unicode string containing non-ASCII characters."""
    value = "Привет, мир! 你好,世界!"
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 2.24μs -> 2.23μs (0.314% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_basic_empty_string():
    """Test with an empty string."""
    value = ""
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 1.84μs -> 1.89μs (2.75% slower)

def test_render_pdf_basic_meta_and_mime_ignored():
    """Test that meta and mime arguments do not affect output."""
    value = "PDF Content"
    meta = {"irrelevant": True}
    mime = "not-a-real-mime"
    html1, out_mime1 = render_pdf(value, {}, "application/pdf") # 2.18μs -> 1.87μs (17.0% faster)
    html2, out_mime2 = render_pdf(value, meta, mime) # 708ns -> 641ns (10.5% faster)

# ---------------------------
# Edge Test Cases
# ---------------------------

def test_render_pdf_long_string():
    """Test with a long string (but under 1000 chars)."""
    value = "A" * 999
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 4.37μs -> 4.02μs (8.53% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_special_characters():
    """Test with string containing special HTML and control characters."""
    value = "<script>alert('xss');</script>\n\t\r"
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 2.19μs -> 2.00μs (9.19% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_null_byte():
    """Test with string containing null byte."""
    value = "abc\x00def"
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 2.09μs -> 1.96μs (6.52% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_surrogate_pairs():
    """Test with string containing surrogate pairs (emoji)."""
    value = "PDF 😊🚀"
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 2.33μs -> 2.18μs (6.78% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_non_string_input_raises():
    """Test that non-string input raises AttributeError (since .encode())."""
    with pytest.raises(AttributeError):
        render_pdf(123, {}, "application/pdf") # 1.44μs -> 1.84μs (22.0% slower)
    with pytest.raises(AttributeError):
        render_pdf(None, {}, "application/pdf") # 801ns -> 873ns (8.25% slower)
    with pytest.raises(AttributeError):
        render_pdf(b"bytes", {}, "application/pdf") # 767ns -> 803ns (4.48% slower)

def test_render_pdf_mime_case_insensitive():
    """Test that the mime argument is ignored, even if it's not 'application/pdf'."""
    value = "Test PDF"
    html1, out_mime1 = render_pdf(value, {}, "application/pdf") # 2.29μs -> 2.16μs (6.02% faster)
    html2, out_mime2 = render_pdf(value, {}, "application/other") # 741ns -> 741ns (0.000% faster)

def test_render_pdf_meta_various_types():
    """Test that meta argument is ignored even if it's not a dict."""
    value = "Test PDF"
    html1, out_mime1 = render_pdf(value, {}, "application/pdf") # 2.02μs -> 1.96μs (2.91% faster)
    html2, out_mime2 = render_pdf(value, [], "application/pdf") # 680ns -> 656ns (3.66% faster)
    html3, out_mime3 = render_pdf(value, None, "application/pdf") # 502ns -> 458ns (9.61% faster)

# ---------------------------
# Large Scale Test Cases
# ---------------------------

def test_render_pdf_large_string():
    """Test with a large string (1000 characters)."""
    value = "X" * 1000
    meta = {}
    mime = "application/pdf"
    html, out_mime = render_pdf(value, meta, mime) # 4.36μs -> 4.12μs (5.72% faster)
    expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_many_unique_inputs():
    """Test with many unique small strings to check for determinism and no caching."""
    for i in range(100):
        value = f"PDF-{i}"
        html, out_mime = render_pdf(value, {}, "application/pdf") # 48.1μs -> 42.7μs (12.5% faster)
        expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

def test_render_pdf_performance_under_load():
    """Test that function can process 500 different values quickly."""
    # Not a strict performance test, but ensures no excessive slowdowns or memory leaks
    for i in range(500):
        value = "A" * (i % 100 + 1)
        html, out_mime = render_pdf(value, {}, "application/pdf") # 275μs -> 248μs (10.9% faster)
        expected_b64 = base64.b64encode(value.encode('utf-8')).decode("utf-8")

# ---------------------------
# Mutation Testing Guards
# ---------------------------

def test_render_pdf_wrong_base64_fails():
    """Test that if the function does not base64 encode, the test fails."""
    value = "Test123"
    wrong_html = f'<embed src="data:application/pdf;base64,{value}" width="100%" height="100%" type="application/pdf">'
    html, out_mime = render_pdf(value, {}, "application/pdf") # 2.06μs -> 2.06μs (0.097% slower)

def test_render_pdf_wrong_mime_type_fails():
    """Test that the returned MIME type must be exactly 'text/html'."""
    value = "Test123"
    html, out_mime = render_pdf(value, {}, "application/pdf") # 2.02μs -> 1.95μs (3.59% faster)

def test_render_pdf_embed_tag_format():
    """Test that the embed tag is formatted correctly."""
    value = "TestPDF"
    html, out_mime = render_pdf(value, {}, "application/pdf") # 1.97μs -> 1.99μs (1.01% slower)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from __future__ import annotations

import base64  # used to verify base64 encoding in test cases

# imports
import pytest  # used for our unit tests
from panel.io.mime_render import render_pdf

# unit tests

# --- Basic Test Cases ---

def test_render_pdf_basic_string():
    # Test with a simple string
    value = "Hello, PDF!"
    meta = {}  # meta is unused
    mime = "application/pdf"  # mime is unused
    html, mime_type = render_pdf(value, meta, mime) # 2.47μs -> 2.28μs (8.33% faster)
    # The output should be an HTML embed tag containing the base64-encoded value
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")
    expected_src = f'data:application/pdf;base64,{expected_base64}'

def test_render_pdf_empty_string():
    # Test with an empty string
    value = ""
    html, mime_type = render_pdf(value, {}, "application/pdf") # 2.00μs -> 1.93μs (3.53% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")
    expected_src = f'data:application/pdf;base64,{expected_base64}'

def test_render_pdf_unicode_string():
    # Test with Unicode characters
    value = "你好, PDF! 🚀"
    html, mime_type = render_pdf(value, {}, "application/pdf") # 2.39μs -> 2.43μs (1.65% slower)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_special_characters():
    # Test with special characters
    value = "<>&\"'/%$#@!"
    html, mime_type = render_pdf(value, {}, "application/pdf") # 2.08μs -> 1.96μs (6.02% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

# --- Edge Test Cases ---

def test_render_pdf_long_string():
    # Test with a long string (edge of typical usage)
    value = "A" * 1024  # 1KB of 'A'
    html, mime_type = render_pdf(value, {}, "application/pdf") # 4.46μs -> 4.20μs (6.27% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_non_ascii_bytes():
    # Test with non-ASCII characters that encode to multiple bytes
    value = "𝄞" * 10  # Musical symbol G clef, 4 bytes each
    html, mime_type = render_pdf(value, {}, "application/pdf") # 2.45μs -> 2.23μs (9.72% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_meta_and_mime_ignored():
    # Test that meta and mime do not affect output
    value = "PDF"
    meta1 = {"foo": "bar"}
    meta2 = None
    mime1 = "application/pdf"
    mime2 = "application/octet-stream"
    html1, mime_type1 = render_pdf(value, meta1, mime1) # 2.09μs -> 1.89μs (10.3% faster)
    html2, mime_type2 = render_pdf(value, meta2, mime2) # 696ns -> 631ns (10.3% faster)

def test_render_pdf_numeric_string():
    # Test with a numeric string
    value = "1234567890"
    html, mime_type = render_pdf(value, {}, "application/pdf") # 1.97μs -> 1.86μs (5.84% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_newlines_and_tabs():
    # Test with string containing newlines and tabs
    value = "Line1\nLine2\tTabbed"
    html, mime_type = render_pdf(value, {}, "application/pdf") # 2.00μs -> 2.01μs (0.199% slower)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_invalid_type_raises():
    # Test with a non-string value (should raise AttributeError)
    with pytest.raises(AttributeError):
        render_pdf(123, {}, "application/pdf") # 1.47μs -> 1.75μs (16.4% slower)
    with pytest.raises(AttributeError):
        render_pdf(None, {}, "application/pdf") # 866ns -> 839ns (3.22% faster)
    with pytest.raises(AttributeError):
        render_pdf([1,2,3], {}, "application/pdf") # 627ns -> 775ns (19.1% slower)

# --- Large Scale Test Cases ---

def test_render_pdf_large_string():
    # Test with a large string (near 1000 bytes)
    value = "B" * 999
    html, mime_type = render_pdf(value, {}, "application/pdf") # 4.78μs -> 4.41μs (8.53% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_many_unique_strings():
    # Test rendering many unique strings for determinism and performance
    for i in range(100):
        value = f"PDF-{i}-{'X'*10}"
        html, mime_type = render_pdf(value, {}, "application/pdf") # 49.5μs -> 44.9μs (10.3% faster)
        expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_large_unicode_string():
    # Test with a large Unicode string
    value = "🚀" * 500  # Each rocket is multi-byte
    html, mime_type = render_pdf(value, {}, "application/pdf") # 6.63μs -> 6.52μs (1.72% faster)
    expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")

def test_render_pdf_stress_varied_inputs():
    # Stress test with varied inputs under 1000 elements
    for i in range(50):
        value = chr(65 + (i % 26)) * (i + 1) + "\n" + str(i)
        html, mime_type = render_pdf(value, {}, "application/pdf") # 29.5μs -> 26.6μs (11.0% faster)
        expected_base64 = base64.b64encode(value.encode("utf-8")).decode("utf-8")
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-render_pdf-mhah5arm and push.

Codeflash

The optimization eliminates an unnecessary intermediate variable assignment by combining the base64 encoding operations into a single chained expression. Instead of storing `value.encode('utf-8')` in a `data` variable and then separately creating the `base64_pdf` variable, the optimized version directly chains `base64.b64encode(value.encode('utf-8')).decode("utf-8")`.

This reduces the number of variable assignments from 3 to 1, eliminating the overhead of creating and storing the intermediate `data` and `src` variables. The `src` variable removal is particularly beneficial as it avoids creating an intermediate f-string that's only used once in the return statement.

The optimization works well across all test scenarios, showing consistent 6-12% improvements for most string inputs. It's especially effective for:
- Basic ASCII strings (6-17% faster)
- Long strings and bulk processing (8-12% faster) 
- Repeated operations with many unique inputs (10-12% faster)

The performance gain comes from reduced memory allocation and fewer Python bytecode operations, while maintaining identical functionality and output.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 October 28, 2025 11:19
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant