gopcua / opcua

Native Go OPC-UA library
MIT License
829 stars 253 forks source link

Feture: Reduce memory allocation during the Encode process to improve encoding performance. #727

Open ethan256 opened 1 month ago

ethan256 commented 1 month ago

The current encoding process generates a large amount of memory allocation, and the GC pressure will increase when the QPS becomes large. Consider reducing the number of memory allocations to optimize the encoding process.

Here is my proposal:

  1. Modify the BinaryEncoderinterface definition

    type BinaryEncoder interface {
    Encode(s *Stream)
    }

    Reduce NewBuffercalls by stitching each field encoding result directly through Stream. the Streamdefinition is as follows:

    type Stream struct {
    buf []byte
    byte []byte
    err error
    }

    Streamimplements the WriteXxxmethod from the original Buffer.

  2. The Encodemethods of all types that implement the BinaryEncoderinterface require only minor modifications, such as DataValue:

    func (d *DataValue) Encode(s *Stream) {
    s.WriteUint8(d.EncodingMask)
    
    if d.Has(DataValueValue) {
        s.WriteAny(d.Value)
    }
    if d.Has(DataValueStatusCode) {
        s.WriteUint32(uint32(d.Status))
    }
    if d.Has(DataValueSourceTimestamp) {
        s.WriteTime(d.SourceTimestamp)
    }
    if d.Has(DataValueSourcePicoseconds) {
        s.WriteUint16(d.SourcePicoseconds)
    }
    if d.Has(DataValueServerTimestamp) {
        s.WriteTime(d.ServerTimestamp)
    }
    if d.Has(DataValueServerPicoseconds) {
        s.WriteUint16(d.ServerPicoseconds)
    }
    }

For detailed implementation, please refer to https://github.com/gopcua/opcua/pull/726