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  }