Skip to content

Bug: Calling PropertyValue.Create to handle boxing is significantly slower than allocating an IReference directly #1416

Description

@sylveon

Version

2.0.240405.15

Summary

This takes 30ms to execute:

winrt::Windows::Foundation::IInspectable ref = nullptr;
for (int i = 0; i < 200000; i++)
    ref = winrt::box_value(i + 1);

This takes 8ms to execute:

winrt::Windows::Foundation::IInspectable ref = nullptr;
for (int i = 0; i < 200000; i++)
    ref = winrt::make<winrt::impl::reference<int>>(i + 1);

It seems weird for box_value to be using PropertyValue.CreateInt32 when just directly allocating a wrapper is significantly faster.

Reproducible example

int main()
{
    winrt::init_apartment();
    const auto before = std::chrono::high_resolution_clock::now();

    winrt::Windows::Foundation::IInspectable ref = nullptr;
    for (int i = 0; i < 200000; i++)
        ref = winrt::box_value(i + 1);

    const auto after = std::chrono::high_resolution_clock::now();
    const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(after - before);
    std::cout << duration.count();
}

Expected behavior

I expected boxing to be fast.

Actual behavior

It's kinda slow.

Additional comments

Spotted this while looking into microsoft/microsoft-ui-xaml#9154

WPF users are expecting WinUI 3 to match WPF performance - and setting 200k DPs takes 21ms with WPF, but 130ms with WinUI 3. We ought to try and match that speed where possible, and this should help by cutting middlemans, at least in C++.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions