Repository: microsoft/terminal
File: src/renderer/uia/UiaRenderer.cpp (C++)

Code before:
{
    RETURN_HR_IF(S_FALSE, !_isEnabled);

    // add more events here
    const bool somethingToDo = _selectionChanged || _textBufferChanged || _cursorChanged;

    // If there's nothing to do, quick return
    RETURN_HR_IF(S_FALSE, !somethingToDo);

    _isPainting = true;
    return S_OK;
}

// Routine Description:
// - Ends batch drawing and notifies automation clients of updated regions
// Arguments:
// - <none>
// Return Value:
// - S_OK, else an appropriate HRESULT for failing to allocate or write.
[[nodiscard]] HRESULT UiaEngine::EndPaint() noexcept
{
    // Snap this now while we're still under lock
    // so present can work on the copy while another
    // thread might start filling the next "frame"
    // worth of text data.
    _queuedOutput = std::move(_newOutput);
    return S_OK;
}

// RenderEngineBase defines a WaitUntilCanRender() that sleeps for 8ms to throttle rendering.
// But UiaEngine is never the only engine running. Overriding this function prevents
// us from sleeping 16ms per frame, when the other engine also sleeps for 8ms.
void UiaEngine::WaitUntilCanRender() noexcept
{
}

// Routine Description:
// - Used to perform longer running presentation steps outside the lock so the
//      other threads can continue.
// - Not currently used by UiaEngine.
// Arguments:
// - <none>
// Return Value:
// - S_FALSE since we do nothing.
[[nodiscard]] HRESULT UiaEngine::Present() noexcept
{
    RETURN_HR_IF(S_FALSE, !_isEnabled);
    RETURN_HR_IF(E_INVALIDARG, !_isPainting); // invalid to end paint when we're not painting

    // Fire UIA Events here
    if (_selectionChanged)

Review comment (suggestion):
You can make your engine reuse previously allocated memory, by writing:
```cpp
std::swap(_queuedOutput, _newOutput);
_newOutput.clear();
```

Instead of calling it `_queuedOutput` / `_newOutput` you could call these two strings `frontBuffer` and `backBuffer`, because they technically work just like the front and back buffers for a swap chain.
(This works because `BeginPaint`, `EndPaint`, etc. aren't called again until the previous `Present()` has finished.)

Once you do that the `_newOutput += newText;` will be very performant since memory copies are extremely fast (in the order of >10GB/s).

Code after:
[[nodiscard]] HRESULT UiaEngine::StartPaint() noexcept
{
    RETURN_HR_IF(S_FALSE, !_isEnabled);

    // add more events here
    const bool somethingToDo = _selectionChanged || _textBufferChanged || _cursorChanged || !_queuedOutput.empty();

    // If there's nothing to do, quick return
    RETURN_HR_IF(S_FALSE, !somethingToDo);

    _isPainting = true;
    return S_OK;
}

// Routine Description:
// - Ends batch drawing and notifies automation clients of updated regions
// Arguments:
// - <none>
// Return Value:
// - S_OK, else an appropriate HRESULT for failing to allocate or write.
[[nodiscard]] HRESULT UiaEngine::EndPaint() noexcept
{
    RETURN_HR_IF(S_FALSE, !_isEnabled);
    RETURN_HR_IF(E_INVALIDARG, !_isPainting); // invalid to end paint when we're not painting

    // Snap this now while we're still under lock
    // so present can work on the copy while another
    // thread might start filling the next "frame"
    // worth of text data.
    std::swap(_queuedOutput, _newOutput);
    _newOutput.clear();
    return S_OK;
}

// RenderEngineBase defines a WaitUntilCanRender() that sleeps for 8ms to throttle rendering.
// But UiaEngine is never the only engine running. Overriding this function prevents
// us from sleeping 16ms per frame, when the other engine also sleeps for 8ms.
void UiaEngine::WaitUntilCanRender() noexcept
{
}

// Routine Description:
// - Used to perform longer running presentation steps outside the lock so the
//      other threads can continue.
// - Not currently used by UiaEngine.
// Arguments:
// - <none>
// Return Value:
// - S_FALSE since we do nothing.
[[nodiscard]] HRESULT UiaEngine::Present() noexcept
{