Skip to content

range-for adapters that batch IVector/IIterable via GetMany #664

Description

@jonwis

Request

range-for adapters over IVector<T> / IVectorView<T> and IIterable<T> (including map IKeyValuePair<K,V>) that prefetch a block per GetMany call instead of crossing the ABI once per element.

Why

Stock range-for is one ABI round-trip per element: GetAt(i) on an indexed collection, or Current + MoveNext on an iterator. GetMany fills a caller buffer in one call, so a block prefetch cuts the crossings to roughly one per block. On a cross-proc or heavily-marshaled collection that's the dominant cost.

Semantics

Single-pass buffering. A buffered element outlives the MoveNext that would otherwise have destroyed it — same observable behavior as wil::to_vector(coll) today, which callers already use for exactly this reason. On the indexed path, random access and E_BOUNDS at/after the end are preserved (an out-of-window index re-anchors the block; an at/after-end index defers to GetAt).

Where

wil/cppwinrt.h. Prototyped in microsoft/cppwinrt#1608 and pulled back out — cppwinrt stays projection-only, adapters live in WIL (sylveon on #1608).

Implementation

Prototype: microsoft/cppwinrt@390e118 (non-GetAt collections — IIterable and map IKeyValuePair — via IIterator::GetMany per block) and microsoft/cppwinrt@ab1f299 (indexed IVector/IVectorView via GetMany block prefetch). Both gate on the element type being default-constructible and the collection actually exposing GetMany, and fall back to per-element GetAt/Current otherwise.

(via Copilot)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions