Skip to content

investigate: by-value struct receiver GC keepalive overhead in encode-shaped loops #4

Description

@hunterjsb

Summary (investigation — not a confirmed minimal repro)

While optimizing a protobuf encoder we saw large self-time in __v_boehm_collect_keepalive on -profile, and switching generated methods from by-value struct receivers (fn (m Msg)) to reference receivers (fn (m &Msg)) produced a measurable, repeatable encode speedup on large messages. The working theory was a per-iteration keepalive walk of the whole receiver inside loops over large fields, i.e. O(n²) behavior.

Filing this as an investigation, not a confirmed bug: minimal isolation attempts on V 0.5.2 5889122 did not reproduce quadratic behavior. Both a read-only sum loop and an allocating append loop over a by-value receiver with a large []u8 scale linearly and run at parity with (or faster than) the &-receiver version. So either the trigger needs a more specific shape than tested, or it has been improved upstream since first observed.

What did not reproduce it

struct Buf { data []u8 }

fn (s Buf) sum_byval() u64 {      // vs fn (s &Buf)
	mut acc := u64(0)
	for i in 0 .. s.data.len { acc += s.data[i] }
	return acc
}

byval/ref ratio ~1.0x across n = 1M/4M/16M; an allocating out << s.data[i] variant likewise linear.

What would confirm or close it

  • The real trigger shape (candidates: by-value receiver whose method calls further methods on nested-struct fields, as generated protobuf encode_to/encoded_size do; arrays of structs; specific GC mode).
  • Or confirmation it is already fixed, in which case close.

Environment

V 0.5.2 5889122, Linux x86_64, -prod.

Note

The downstream code already uses & receivers everywhere, so this is not blocking anything — purely a tracking issue to either pin down or lay to rest.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions