Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Dec 19, 2025

📄 10% (0.10x) speedup for OneNoteDataSource.me_onenote_notebooks_section_groups_sections_update_pages_content in backend/python/app/sources/external/microsoft/one_note/one_note.py

⏱️ Runtime : 649 microseconds 593 microseconds (best of 5 runs)

📝 Explanation and details

The optimization achieves a 9% runtime improvement by eliminating unnecessary object allocation during request configuration setup. Here are the key changes:

What was optimized:

  • Removed duplicate RequestConfiguration allocation: The original code created two separate RequestConfiguration objects - one for query_params and another for config, then assigned the first to the second's query_parameters property
  • Direct config usage: The optimized version creates only one RequestConfiguration instance and sets query parameters directly on it
  • Added defensive copying: Uses headers.copy() to prevent accidental mutation of caller's input headers

Why this improves performance:

  • Reduced memory allocations: Eliminates one unnecessary object creation (line profiler shows the second RequestConfiguration() call took ~1262.6ns per hit in the original)
  • Fewer object assignments: Removes the config.query_parameters = query_params assignment step
  • Streamlined object lifecycle: Single config object reduces garbage collection overhead

Performance impact:
The line profiler shows the optimization saves time in the configuration setup phase (lines creating and assigning RequestConfiguration objects), while the actual API call time remains unchanged. This is expected since the network I/O dominates execution time.

Test case effectiveness:
The optimization benefits all test scenarios equally since every call must build request configuration. The concurrent test cases (5, 50, and 100 operations) would see cumulative benefits from reduced per-operation overhead, though throughput remains constant at 1115 ops/sec due to network I/O being the bottleneck.

This is a clean micro-optimization that maintains identical functionality while reducing unnecessary object creation overhead in the request preparation phase.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 236 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 96.4%
🌀 Generated Regression Tests and Runtime
import asyncio

# Patch the imported classes in the tested module
from typing import Any, Optional

import pytest
from app.sources.external.microsoft.one_note.one_note import OneNoteDataSource

# --- Minimal stubs for dependencies ---


class OneNoteResponse:
    def __init__(self, success: bool, data: Any = None, error: Optional[str] = None):
        self.success = success
        self.data = data
        self.error = error


class DummyPagesContent:
    def __init__(self):
        self.last_args = None
        self.last_kwargs = None

    async def put(self, body=None, request_configuration=None):
        # Simulate a successful PUT operation, echoing back the body and configuration
        self.last_args = (body, request_configuration)
        self.last_kwargs = {}
        # Simulate a response object
        return {"updated": True, "body": body, "config": request_configuration}


class DummyPages:
    def __init__(self):
        self.content = DummyPagesContent()

    def by_onenote_page_id(self, onenotePage_id):
        self.last_page_id = onenotePage_id
        return self


class DummySections:
    def __init__(self):
        self.pages = DummyPages()

    def by_onenote_section_id(self, onenoteSection_id):
        self.last_section_id = onenoteSection_id
        return self


class DummySectionGroups:
    def __init__(self):
        self.sections = DummySections()

    def by_section_group_id(self, sectionGroup_id):
        self.last_section_group_id = sectionGroup_id
        return self


class DummyNotebooks:
    def __init__(self):
        self.section_groups = DummySectionGroups()

    def by_notebook_id(self, notebook_id):
        self.last_notebook_id = notebook_id
        return self


class DummyMe:
    def __init__(self):
        self.onenote = DummyOneNote()


class DummyOneNote:
    def __init__(self):
        self.notebooks = DummyNotebooks()


class DummyMSGraphServiceClient:
    def __init__(self):
        self.me = DummyMe()


class DummyMSGraphClient:
    def get_client(self):
        return self

    def get_ms_graph_service_client(self):
        return DummyMSGraphServiceClient()


class DummyRequestConfiguration:
    def __init__(self):
        self.select = None
        self.expand = None
        self.filter = None
        self.orderby = None
        self.search = None
        self.top = None
        self.skip = None
        self.headers = None
        self.query_parameters = None


# --- Unit Tests ---


@pytest.fixture
def onenote_data_source():
    """Fixture to provide a OneNoteDataSource with a dummy client."""
    return OneNoteDataSource(DummyMSGraphClient())


# 1. Basic Test Cases


@pytest.mark.asyncio
async def test_update_pages_content_basic_success(onenote_data_source):
    """Test basic successful update of OneNote page content."""
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="notebook1",
        sectionGroup_id="sg1",
        onenoteSection_id="section1",
        onenotePage_id="page1",
        request_body={"content": "Hello, world!"},
    )


@pytest.mark.asyncio
async def test_update_pages_content_returns_OnenoteResponse(onenote_data_source):
    """Test that the function always returns an OneNoteResponse."""
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="nb",
        sectionGroup_id="sg",
        onenoteSection_id="sec",
        onenotePage_id="pg",
    )


@pytest.mark.asyncio
async def test_update_pages_content_with_all_parameters(onenote_data_source):
    """Test passing all parameters to the function."""
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="nb2",
        sectionGroup_id="sg2",
        onenoteSection_id="sec2",
        onenotePage_id="pg2",
        select=["id", "title"],
        expand=["parentNotebook"],
        filter="title eq 'Test'",
        orderby="createdDateTime desc",
        search="meeting notes",
        top=10,
        skip=2,
        request_body={"content": "Updated"},
        headers={"Authorization": "Bearer token"},
    )


# 2. Edge Test Cases


@pytest.mark.asyncio
async def test_update_pages_content_with_empty_strings(onenote_data_source):
    """Test with empty string IDs."""
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="",
        sectionGroup_id="",
        onenoteSection_id="",
        onenotePage_id="",
        request_body={"content": "Empty IDs"},
    )


@pytest.mark.asyncio
async def test_update_pages_content_with_none_body(onenote_data_source):
    """Test with None as request_body."""
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="nb3",
        sectionGroup_id="sg3",
        onenoteSection_id="sec3",
        onenotePage_id="pg3",
        request_body=None,
    )


@pytest.mark.asyncio
async def test_update_pages_content_with_invalid_headers(onenote_data_source):
    """Test with headers that are not a dict (should raise and return error)."""
    # Patch the function to simulate an exception in headers assignment
    # Here, we pass a non-dict headers which should be assigned, but our DummyRequestConfiguration allows any type
    # So, let's simulate an error by passing a value that will break config.headers['ConsistencyLevel'] assignment
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="nb4",
        sectionGroup_id="sg4",
        onenoteSection_id="sec4",
        onenotePage_id="pg4",
        search="something",
        headers="notadict",  # This will cause config.headers['ConsistencyLevel'] to fail
    )


@pytest.mark.asyncio
async def test_update_pages_content_concurrent_execution(onenote_data_source):
    """Test concurrent execution of the function."""

    async def call_func(i):
        return await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id=f"nb{i}",
            sectionGroup_id=f"sg{i}",
            onenoteSection_id=f"sec{i}",
            onenotePage_id=f"pg{i}",
            request_body={"content": f"Content {i}"},
        )

    results = await asyncio.gather(*(call_func(i) for i in range(5)))
    for i, resp in enumerate(results):
        pass


@pytest.mark.asyncio
async def test_update_pages_content_exception_handling(
    onenote_data_source, monkeypatch
):
    """Test that exceptions in the client call are handled and returned as error."""
    # Patch the DummyPagesContent.put to raise an exception
    orig_put = DummyPagesContent.put

    async def raise_exc(*args, **kwargs):
        raise RuntimeError("Simulated client error")

    DummyPagesContent.put = raise_exc
    try:
        response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id="nb5",
            sectionGroup_id="sg5",
            onenoteSection_id="sec5",
            onenotePage_id="pg5",
        )
    finally:
        DummyPagesContent.put = orig_put


# 3. Large Scale Test Cases


@pytest.mark.asyncio
async def test_update_pages_content_large_scale_concurrent(onenote_data_source):
    """Test large scale concurrent updates (50 concurrent calls)."""

    async def call_func(i):
        return await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id=f"nb{i}",
            sectionGroup_id=f"sg{i}",
            onenoteSection_id=f"sec{i}",
            onenotePage_id=f"pg{i}",
            request_body={"content": f"Bulk {i}"},
        )

    results = await asyncio.gather(*(call_func(i) for i in range(50)))


@pytest.mark.asyncio
async def test_update_pages_content_large_payload(onenote_data_source):
    """Test with a large request_body."""
    large_body = {"content": "A" * 10000}
    response = await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
        notebook_id="large",
        sectionGroup_id="large",
        onenoteSection_id="large",
        onenotePage_id="large",
        request_body=large_body,
    )


# 4. Throughput Test Cases


@pytest.mark.asyncio
async def test_update_pages_content_throughput_small_load(onenote_data_source):
    """Throughput: Test small batch of concurrent requests."""

    async def call_func(i):
        return await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id=f"nb{i}",
            sectionGroup_id=f"sg{i}",
            onenoteSection_id=f"sec{i}",
            onenotePage_id=f"pg{i}",
            request_body={"content": f"Small {i}"},
        )

    results = await asyncio.gather(*(call_func(i) for i in range(10)))


@pytest.mark.asyncio
async def test_update_pages_content_throughput_medium_load(onenote_data_source):
    """Throughput: Test medium batch of concurrent requests."""

    async def call_func(i):
        return await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id=f"nb{i}",
            sectionGroup_id=f"sg{i}",
            onenoteSection_id=f"sec{i}",
            onenotePage_id=f"pg{i}",
            request_body={"content": f"Medium {i}"},
        )

    results = await asyncio.gather(*(call_func(i) for i in range(50)))


@pytest.mark.asyncio
async def test_update_pages_content_throughput_large_load(onenote_data_source):
    """Throughput: Test large batch of concurrent requests."""

    async def call_func(i):
        return await onenote_data_source.me_onenote_notebooks_section_groups_sections_update_pages_content(
            notebook_id=f"nb{i}",
            sectionGroup_id=f"sg{i}",
            onenoteSection_id=f"sec{i}",
            onenotePage_id=f"pg{i}",
            request_body={"content": f"Large {i}"},
        )

    results = await asyncio.gather(*(call_func(i) for i in range(100)))


# 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-OneNoteDataSource.me_onenote_notebooks_section_groups_sections_update_pages_content-mjc4i9r1 and push.

Codeflash Static Badge

…ns_update_pages_content

The optimization achieves a **9% runtime improvement** by eliminating unnecessary object allocation during request configuration setup. Here are the key changes:

**What was optimized:**
- **Removed duplicate RequestConfiguration allocation**: The original code created two separate `RequestConfiguration` objects - one for `query_params` and another for `config`, then assigned the first to the second's `query_parameters` property
- **Direct config usage**: The optimized version creates only one `RequestConfiguration` instance and sets query parameters directly on it
- **Added defensive copying**: Uses `headers.copy()` to prevent accidental mutation of caller's input headers

**Why this improves performance:**
- **Reduced memory allocations**: Eliminates one unnecessary object creation (line profiler shows the second `RequestConfiguration()` call took ~1262.6ns per hit in the original)
- **Fewer object assignments**: Removes the `config.query_parameters = query_params` assignment step
- **Streamlined object lifecycle**: Single config object reduces garbage collection overhead

**Performance impact:**
The line profiler shows the optimization saves time in the configuration setup phase (lines creating and assigning RequestConfiguration objects), while the actual API call time remains unchanged. This is expected since the network I/O dominates execution time.

**Test case effectiveness:**
The optimization benefits all test scenarios equally since every call must build request configuration. The concurrent test cases (5, 50, and 100 operations) would see cumulative benefits from reduced per-operation overhead, though throughput remains constant at 1115 ops/sec due to network I/O being the bottleneck.

This is a clean micro-optimization that maintains identical functionality while reducing unnecessary object creation overhead in the request preparation phase.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 December 19, 2025 00:20
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Dec 19, 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