2016-03-25 15 views
2

Ich habe ein Programm, das UDP-Pakete sendet. ein Paket-Datagramm durch die folgende Struktur dargestellt wird (man beachte, dass die Größe des Pakets ist nicht festgelegt):Golan effiziente binäre Codierung

type packet struct { 
    dataLength uint16 
    id [8]byte 
    pairity, shards, flags byte 
    blob []byte // length defined by dataLength 
} 

I encoding/Binärpakets verwenden Serialisierung/Deserialisierung zu tun, aber es war nicht effizient genug (verwendetes pprof). es hat viel CPU-Zeit verschwendet und ich konnte deswegen nicht die gesamte Netzwerkgeschwindigkeit nutzen.

Betrachten wir zum Beispiel den folgenden Code:

packet := packet{ 
    dataLength: 4, 
    id: [8]byte{1,2,3,4,5,6,7,8}, 
    pairity: 10, 
    shards: 50, 
    flags: 200, 
    blob: []byte{1,2,3,4}, 
} 
bufToSendOverNetwork := packet.ToBytes() 

Was die effizienteste Weg ist, um diesen Vorgang zu tun (und auch die .FromBytes Betrieb)

+0

Können Sie die Binärcodierung zeigen, die Sie gerade verwenden, und wo ist Ihr Engpass? Da 'blob' ein Slice ist, ist Ihre Go-Struktur nicht etwas, das direkt geschrieben wird, um mit der Paketstruktur übereinzustimmen. – JimB

Antwort

2

encoding/binary.Write verwendet Reflektion, so dass es langsamer sein wird als alles, was den Puffer manuell erstellt. Im Folgenden finden Sie ein Beispiel für eine solche Funktion:

import (
    "encoding/binary" 
) 

func (p *packet) ToBytes() []byte { 
    buff := make([]byte, 2 + 8 + 3 + len(p.blob)) 

    binary.BigEndian.PutUint16(buff[:2], p.dataLength) 
    copy(buff[2:10], p.id[:]) 
    buff[10] = p.pairity 
    buff[11] = p.shards 
    buff[12] = p.flags 
    copy(buff[13:], p.blob) 

    return buff 
}