### No Code Found in Project /bufbuild/hyperpb-go Source: https://github.com/bufbuild/hyperpb-go/blob/main/internal/swiss/benchdata/english.txt The provided content for the /bufbuild/hyperpb-go project does not contain any code snippets or programming examples. Therefore, no documentation can be generated for code. -------------------------------- ### Compile File Descriptor with Hyperpb Extension Options Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Compiles a file descriptor using hyperpb, allowing configuration of extension resolution. This example shows how to use `hyperpb.WithExtensionsFromTypes` to specify a type registry for resolving extensions. ```Go msgType, err := hyperpb.CompileFileDescriptor( schema, messageName, hyperpb.WithExtensionsFromTypes(typeRegistry), // Additional options... ) ``` -------------------------------- ### Go Parser Thunk Specialization Example Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Illustrates the concept of hyper-specialized parser thunks. Instead of a single thunk with internal branching, separate thunks are used for different field types (e.g., optional vs. singular) to minimize branch mispredictions and improve performance. ```go // Thunk for optional fields func (p *P1) OptionalFieldThunk(data []byte) { // ... logic specific to optional fields } // Thunk for singular fields func (p *P1) SingularFieldThunk(data []byte) { // ... logic specific to singular fields } ``` -------------------------------- ### Compile and Parse Protobuf Message with Hyperpb in Go Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md This Go code demonstrates the core usage of the hyperpb library. It compiles a message descriptor for a WeatherReport, creates a new message instance, and then unmarshals byte data into it. The example further illustrates accessing message fields and repeated fields using the reflection API provided by hyperpb. ```Go package main import ( "fmt" "log" "buf.build/go/hyperpb" "google.golang.org/protobuf/proto" weatherv1 "buf.build/gen/go/bufbuild/hyperpb-examples/protocolbuffers/go/example/weather/v1" ) // Byte slice representation of a valid *weatherv1.WeatherReport. var weatherDataBytes = []byte{ 0x0a, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x05, 0x4b, 0x41, 0x44, 0x39, 0x33, 0x15, 0x66, 0x86, 0x22, 0x43, 0x1d, 0xcd, 0xcc, 0x34, 0x41, 0x25, 0xd7, 0xa3, 0xf0, 0x41, 0x2d, 0x33, 0x33, 0x13, 0x40, 0x30, 0x03, 0x12, 0x1d, 0x0a, 0x05, 0x4b, 0x48, 0x42, 0x36, 0x30, 0x15, 0xcd, 0x8c, 0x22, 0x43, 0x1d, 0x33, 0x33, 0x5b, 0x41, 0x25, 0x52, 0xb8, 0xe0, 0x41, 0x2d, 0x33, 0x33, 0xf3, 0x3f, 0x30, 0x03, } func main() { // Compile a type for your message. Make sure to cache this! // Here, we're using a compiled-in descriptor. msgType := hyperpb.CompileMessageDescriptor( (*weatherv1.WeatherReport)(nil).ProtoReflect().Descriptor(), ) // Allocate a fresh message using that type. msg := hyperpb.NewMessage(msgType) // Parse the message, using proto.Unmarshal like any other message type. if err := proto.Unmarshal(weatherDataBytes, msg); err != nil { // Handle parse failure. log.Fatalf("failed to parse weather data: %v", err) } // Use reflection to read some fields. hyperpb currently only supports access // by reflection. You can also look up fields by index using fields.Get(), which // is less legible but doesn't hit a hashmap. fields := msgType.Descriptor().Fields() // Get returns a protoreflect.Value, which can be printed directly... fmt.Println(msg.Get(fields.ByName("region"))) // ... or converted to an explicit type to operate on, such as with List(), // which converts a repeated field into something with indexing operations. stations := msg.Get(fields.ByName("weather_stations")).List() for i := range stations.Len() { // Get returns a protoreflect.Value too, so we need to convert it into // a message to keep extracting fields. station := stations.Get(i).Message() fields := station.Descriptor().Fields() // Here we extract each of the fields we care about from the message. // Again, we could use fields.Get if we know the indices. fmt.Println("station:", station.Get(fields.ByName("station"))) fmt.Println("frequency:", station.Get(fields.ByName("frequency"))) fmt.Println("temperature:", station.Get(fields.ByName("temperature"))) fmt.Println("pressure:", station.Get(fields.ByName("pressure"))) fmt.Println("wind_speed:", station.Get(fields.ByName("wind_speed"))) fmt.Println("conditions:", station.Get(fields.ByName("conditions"))) } } ``` -------------------------------- ### Memory Reuse with Hyperpb Shared Context Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Illustrates memory reuse in hyperpb by retaining `hyperpb.Shared` state across message lifecycles. This example shows a request context that manages shared resources for creating and freeing messages, bypassing the Go garbage collector for improved allocation latency. ```Go type requestContext struct { shared *hyperpb.Shared types map[string]*hyperpb.MessageType // Additional context fields... } func (c *requestContext) Handle(req Request) { msgType := c.types[req.Type] msg := c.shared.NewMessage(msgType) defer c.shared.Free() c.process(msg, req, ...) } ``` -------------------------------- ### Go Reusable Parser Thunks Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Demonstrates the reuse of parser thunks across similar archetypes to improve instruction cache friendliness. For example, int32, uint32, and enum fields might share a thunk as they are all parsed and stored as 32-bit varints. ```go // Thunk for 32-bit varint fields (int32, uint32, enum) func (p *P1) Varint32Thunk(data []byte) { // ... parse and store as 32-bit varint } // Thunk for fixed 32-bit fields (fixed32, sfixed32, float32) func (p *P1) Fixed32Thunk(data []byte) { // ... parse and store as fixed 32-bit value } ``` -------------------------------- ### Run CPU Profile Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Generates a CPU profile for the project and displays it locally using pprof. This is useful for identifying performance bottlenecks. ```Shell make profile ``` -------------------------------- ### Run All Benchmarks Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Executes all benchmarks for the project to ensure performance integrity. This command is part of the makefile for convenient testing. ```Shell make bench ``` -------------------------------- ### No code snippets found for this project. Source: https://github.com/bufbuild/hyperpb-go/blob/main/internal/swiss/benchdata/english.txt The provided content does not contain any executable code snippets. -------------------------------- ### Dynamic Recompilation with Sampling in Go Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Demonstrates how to dynamically recompile hyperpb.MessageType using a custom sampling rate for online optimization. It includes handling requests, profiling messages with a specified sampling rate, and asynchronously recompiling types when a certain threshold of messages has been seen. ```Go type requestContext struct { shared *hyperpb.Shared types map[string]*typeInfo // Additional context fields... } type typeInfo struct { msgType atomic.Pointer[hyperpb.MessageType] prof atomic.Pointer[hyperpb.Profile] seen atomic.Int64 } func (c *requestContext) Handle(req Request) { // Look up the type in the context's type map. typeInfo := c.types[req.Type] // Parse the type as usual. msg := c.shared.NewMessage(typeInfo.msgType.Load()) defer c.shared.Free() if err := msg.Unmarshal( data, // Only profile 1% of messages. hyperpb.WithRecordProfile(typeInfo.prof.Load(), 0.01), ); err != nil { // Process error... } typeInfo.seen.Add(1) // Every 100,000 messages, spawn a goroutine to asynchronously recompile the type. if typeInfo.seen.Load() % 100000 == 0 { go func() { prof := typeInfo.prof.Load() if !typeInfo.prof.CompareAndSwap(prof, nil) { // Avoid a race condition. return } // Recompile the type. This is gonna be really slow, because // the compiler is slow, which is why we're doing it asynchronously. typeInfo.msgType.Store(typeInfo.msgType.Load().Recompile(typeInfo.prof.Load())) typeInfo.prof.Store(typeInfo.msgType.Load().NewProfile()) } } // Do something with msg. } ``` -------------------------------- ### Dump Assembly Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Dumps the assembly code of the benchmarks for manual inspection. This can help in understanding low-level performance characteristics. ```Shell make asm ``` -------------------------------- ### Go Main Interpreter Loop Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md The main loop of the interpreter is implemented as vm.loop. It's structured as a strongly connected component of blocks joined by gotos, allowing jumps between sections for partial tag decoding, tag matching, and resynchronization. ```go func loop() { // ... main loop logic with goto statements } ``` -------------------------------- ### Inlined Varint Decoding in Go Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Demonstrates the manual inlining of protowire's ConsumeVarint for field value decoding. This approach significantly improves performance by removing redundant bounds checks and branches, as Go's default inlining heuristics are insufficient for this hot function. ```go func consumeVarint(r io.Reader) (uint64, error) { // Inlined copy of protowire.ConsumeVarint var x uint64 var s uint for i := 0; i < 10; i++ { buf := make([]byte, 1) if _, err := r.Read(buf); err != nil { if err == io.EOF { return 0, io.ErrUnexpectedEOF } return 0, err } b := uint64(buf[0]) if b < 0x80 { return x | (b << s), } x |= (b & 0x7f) << s s += 7 if s >= 64 { return 0, errors.New("protowire: varint overflow") } } return 0, errors.New("protowire: varint overflow") } ``` -------------------------------- ### Process Dynamic Message with Hyperpb Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Parses a dynamic message using a schema and message name, then unmarshals data into the message and iterates over its fields. Requires the descriptorpb.FileDescriptorSet schema and protoreflect.FullName message name. ```Go func processDynamicMessage( schema *descriptorpb.FileDescriptorSet, messageName protoreflect.FullName, data []byte, ) error { msgType, err := hyperpb.CompileFileDescriptorSet(schema, messageName) // Remember to cache this! if err != nil { return err } msg := hyperpb.NewMessage(msgType) if err := proto.Unmarshal(data, msg); err != nil { return err } // Range will iterate over all of the populated fields in msg. Here we // use Range with go1.24 iterator syntax. for field, value := range msg.Range { // Do something with each populated field. } return nil } ``` -------------------------------- ### Unmarshal Message with Custom Hyperpb Options Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Demonstrates unmarshalling a message with custom options for fine-grained control over the decoding process. This method allows setting options like `WithMaxDecodeMisses` for performance tuning. It requires the schema, message name, and raw data. ```Go func unmarshalWithCustomOptions( schema *descriptorpb.FileDescriptorSet, messageName protoreflect.FullName, data []byte, ) error { msgType, err := hyperpb.CompileFileDescriptorSet(schema, messageName) if err != nil { return err } msg := hyperpb.NewMessage(msgType) return msg.Unmarshal( data, hyperpb.WithMaxDecodeMisses(16), // Additional options... ) } ``` -------------------------------- ### Compile PGO Optimized Type in Go Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Compiles a Protobuf message descriptor into an optimized hyperpb.MessageType using a corpus of messages as a profile. It involves creating a profile recorder, parsing specimens to record profile data, and then recompiling the message type with the collected profile. ```Go func compilePGO( md protoreflect.MessageDescriptor, corpus [][]byte, ) (*hyperpb.MessageType, error) { // Compile the type without any profiling information. msgType := hyperpb.CompileMessageDescriptor(md) // Construct a new profile recorder. profile := msgType.NewProfile() // Parse all of the specimens in the corpus, making sure to record a profile // for all of them. s := new(hyperpb.Shared) for _, specimen := range corpus { if err := s.NewMessage(msgType).Unmarshal( specimen, hyperpb.WithRecordProfile(profile, 1.0), ); err != nil { return nil, err } s.Free() } // Recompile with the profile. return msgType.Recompile(profile), nil } ``` -------------------------------- ### Convert Dynamic Message to JSON with Hyperpb Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Converts a dynamically received message into JSON format. It first compiles the message type from a schema, unmarshals the data, and then marshals the message to JSON. Dependencies include hyperpb, proto, and protojson packages. ```Go func dynamicMessageToJSON( schema *descriptorpb.FileDescriptorSet, messageName protoreflect.FullName, data []byte, ) ([]byte, error) { msgType, err := hyperpb.CompileFileDescriptorSet(schema, messageName) if err != nil { return nil, err } msg := hyperpb.NewMessage(msgType) if err := proto.Unmarshal(data, msg); err != nil { return nil, err } // Dump the message to JSON. This just works! return protojson.Marshal(msg) } ``` -------------------------------- ### Validate Dynamic Message with Protovalidate and Hyperpb Source: https://github.com/bufbuild/hyperpb-go/blob/main/README.md Validates a dynamically loaded message using protovalidate. It first compiles the message type and unmarshals the data, then applies validation rules. This function requires the schema, message name, and message data. ```Go func validateDynamicMessage( schema *descriptorpb.FileDescriptorSet, messageName protoreflect.FullName, data []byte, ) error { // Unmarshal like before. msgType, err := hyperpb.CompileFileDescriptorSet(schema, messageName) if err != nil { return err } msg := hyperpb.NewMessage(msgType) if err := proto.Unmarshal(data, msg); err != nil { return err } // Run custom validation. This just works! return protovalidate.Validate(msg) } ``` -------------------------------- ### Go Parser VM State Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md The parser's state is divided into three types: vm.P1, vm.P2, and vm.p3. These are used to work around Go codegen bugs and improve performance. They should be considered as a single logical entity representing the parser's state. ```go type P1 struct { // ... state fields } type P2 struct { // ... state fields } type p3 struct { // ... state fields } ``` -------------------------------- ### Go Partial Tag Decode Logic Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md This section handles the partial decoding of a field tag. It loads bytes, uses bit tricks to count sign bits for varint length, and masks bytes to isolate relevant data. It also clears sign bits and advances the parser past the varint. ```go // Load eight bytes var data uint64 // ... read bytes into data // Count sign bits using bit tricks var signBits = bits.LeadingZeros64(^data) // Mask off irrelevant bytes based on varint length // ... masking logic // Clear sign bits // ... clearing logic // Advance parser past varint // ... advance logic ``` -------------------------------- ### Go Tag Matching and Field Thunk Execution Source: https://github.com/bufbuild/hyperpb-go/blob/main/DESIGN.md Compares the partially decoded tag with expected tags for each field. If a match is found, the corresponding parser thunk is called to consume the field's value. Thunks may advance the field table pointer based on predictions for packed or non-packed fields. ```go func (p *P1) Field() { // ... partial tag decode logic // Compare tag with expected field tags if tag == expectedTag { // Call parser thunk p.thunk(fieldData) // ... potentially advance field pointer } else { // ... fallback logic } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.