github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kson/kson_test.go (about) 1 package kson 2 3 import ( 4 "encoding/binary" 5 "encoding/json" 6 "testing" 7 "time" 8 ) 9 10 type TcpPacket struct { 11 Time time.Time 12 SrcIp string 13 SrcPort uint16 14 DstIp string 15 DstPort uint16 16 Seq uint32 17 Ack uint32 18 //Len int 19 //ACK bool 20 //SYN bool 21 //FIN bool 22 //RST bool 23 //Window uint16 // 2-65535 必须乘 SYN里面的WindowScale值. 24 //WindowScale uint8 // 0 表示没有这一项 SYN里面的WindowScale值. 25 //TimeStamp uint32 // tcp的timestamp扩展里面的对方发过来的时间. 26 // 27 // // 其他参数似乎没有什么作用,直接忽略 28 //connId string 29 //id string 30 //ackId string 31 } 32 33 func MarshalTcpPacket(o *TcpPacket) (b []byte, err error) { 34 timeb, err := o.Time.MarshalBinary() //13.73% 35 if err != nil { 36 return nil, err 37 } 38 timeBSize := len(timeb) 39 srcIpSize := len(o.SrcIp) 40 dstIpSize := len(o.DstIp) 41 size := 1 + timeBSize + 1 + srcIpSize + 2 + 1 + dstIpSize + 2 + 4 + 4 42 b = make([]byte, size) // 24.44% 43 pos := 0 44 b[pos] = byte(timeBSize) 45 pos++ 46 copy(b[pos:pos+timeBSize], timeb) 47 pos += timeBSize 48 49 b[pos] = byte(srcIpSize) 50 pos++ 51 copy(b[pos:pos+srcIpSize], o.SrcIp) 52 pos += srcIpSize 53 54 binary.LittleEndian.PutUint16(b[pos:pos+2], o.SrcPort) 55 pos += 2 56 57 b[pos] = byte(dstIpSize) 58 pos++ 59 copy(b[pos:pos+srcIpSize], o.SrcIp) 60 pos += dstIpSize 61 62 binary.LittleEndian.PutUint16(b[pos:pos+2], o.DstPort) 63 pos += 2 64 65 binary.LittleEndian.PutUint32(b[pos:pos+4], o.Seq) 66 pos += 4 67 68 binary.LittleEndian.PutUint32(b[pos:pos+4], o.Ack) 69 pos += 4 70 71 return b, nil 72 } 73 74 func UnmarshalTcpPacket(b []byte) (packet *TcpPacket, err error) { 75 packet = &TcpPacket{} // 13.73% 76 pos := 0 77 timeSize := b[pos] 78 pos++ 79 err = packet.Time.UnmarshalBinary(b[pos : pos+int(timeSize)]) //4.39% 80 if err != nil { 81 return nil, err 82 } 83 pos += int(timeSize) 84 85 sSize := b[pos] 86 packet.SrcIp = string(b[pos : pos+int(sSize)]) //12.48% 87 pos += int(sSize) 88 89 packet.SrcPort = binary.LittleEndian.Uint16(b[pos : pos+2]) 90 pos += 2 91 92 sSize = b[pos] 93 packet.DstIp = string(b[pos : pos+int(sSize)]) 94 pos += int(sSize) 95 96 packet.DstPort = binary.LittleEndian.Uint16(b[pos : pos+2]) 97 pos += 2 98 99 packet.Seq = binary.LittleEndian.Uint32(b[pos : pos+4]) 100 pos += 4 101 102 packet.Ack = binary.LittleEndian.Uint32(b[pos : pos+4]) 103 pos += 4 104 return packet, nil 105 } 106 107 /* 108 BenchmarkJsonMarshal-4 300000 4235 ns/op 28.80 MB/s 600 B/op 7 allocs/op 109 BenchmarkJsonUnmarshal-4 200000 6197 ns/op 19.68 MB/s 400 B/op 9 allocs/op 110 BenchmarkKsonMarshal-4 10000000 213 ns/op 205.85 MB/s 64 B/op 2 allocs/op 111 BenchmarkKsonUnmarshal-4 10000000 223 ns/op 197.04 MB/s 96 B/op 2 allocs/op 112 113 */ 114 func BenchmarkJsonMarshal(b *testing.B) { 115 data := TcpPacket{ 116 Time: time.Now().In(time.UTC), 117 SrcIp: "1.2.3.4", 118 DstIp: "1.2.3.4", 119 } 120 total := 0 121 b.ResetTimer() 122 for i := 0; i < b.N; i++ { 123 buf, err := json.Marshal(data) 124 if err != nil { 125 panic(err) 126 } 127 total += len(buf) 128 } 129 b.SetBytes(int64(total / b.N)) 130 } 131 132 func BenchmarkJsonUnmarshal(b *testing.B) { 133 data := TcpPacket{ 134 Time: time.Now().In(time.UTC), 135 SrcIp: "1.2.3.4", 136 DstIp: "1.2.3.4", 137 } 138 buf, err := json.Marshal(data) 139 if err != nil { 140 panic(err) 141 } 142 b.SetBytes(int64(len(buf))) 143 b.ResetTimer() 144 for i := 0; i < b.N; i++ { 145 err := json.Unmarshal(buf, &data) 146 if err != nil { 147 panic(err) 148 } 149 } 150 } 151 152 func BenchmarkKsonMarshal(b *testing.B) { 153 data := &TcpPacket{ 154 Time: time.Now().In(time.UTC), 155 SrcIp: "1.2.3.4", 156 DstIp: "1.2.3.4", 157 } 158 total := 0 159 b.ResetTimer() 160 for i := 0; i < b.N; i++ { 161 buf, err := MarshalTcpPacket(data) 162 if err != nil { 163 panic(err) 164 } 165 total += len(buf) 166 } 167 b.SetBytes(int64(total / b.N)) 168 } 169 170 func BenchmarkKsonUnmarshal(b *testing.B) { 171 data := &TcpPacket{ 172 Time: time.Now().In(time.UTC), 173 SrcIp: "1.2.3.4", 174 DstIp: "1.2.3.4", 175 } 176 buf, err := MarshalTcpPacket(data) 177 if err != nil { 178 panic(err) 179 } 180 b.SetBytes(int64(len(buf))) 181 b.ResetTimer() 182 for i := 0; i < b.N; i++ { 183 _, err := UnmarshalTcpPacket(buf) 184 if err != nil { 185 panic(err) 186 } 187 } 188 }