github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kson/ksonv2_test.go (about)

     1  package kson
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  	"unsafe"
    10  )
    11  
    12  func MarshalTcpPacketV2(o *TcpPacket) (b []byte, err error) {
    13  	//timeb,err:=o.Time.MarshalBinary() //13.73%
    14  	//if err!=nil{
    15  	//	return nil,err
    16  	//}
    17  	//timeBSize:=len(timeb)
    18  	srcIpSize := len(o.SrcIp)
    19  	dstIpSize := len(o.DstIp)
    20  	//size:=1+timeBSize+1+srcIpSize+2+1+ dstIpSize +2+4+4
    21  	size := 1 + srcIpSize + 2 + 1 + dstIpSize + 2 + 4 + 4
    22  	b = make([]byte, size) // 24.44%
    23  	pos := 0
    24  	//b[pos] = byte(timeBSize)
    25  	//pos++
    26  	//copy(b[pos:pos+timeBSize],timeb)
    27  	//pos+=timeBSize
    28  
    29  	b[pos] = byte(srcIpSize)
    30  	pos++
    31  	copy(b[pos:pos+srcIpSize], o.SrcIp)
    32  	pos += srcIpSize
    33  
    34  	b[pos] = byte(o.SrcPort)
    35  	b[pos+1] = byte(o.SrcPort >> 8)
    36  	//binary.LittleEndian.PutUint16(b[pos:pos+2],o.SrcPort)
    37  	pos += 2
    38  
    39  	b[pos] = byte(dstIpSize)
    40  	pos++
    41  	copy(b[pos:pos+srcIpSize], o.SrcIp)
    42  	pos += dstIpSize
    43  
    44  	b[pos] = byte(o.DstPort)
    45  	b[pos+1] = byte(o.DstPort >> 8)
    46  	//binary.LittleEndian.PutUint16(b[pos:pos+2],o.DstPort)
    47  	pos += 2
    48  
    49  	b[pos] = byte(o.Seq)
    50  	b[pos+1] = byte(o.Seq >> 8)
    51  	b[pos+2] = byte(o.Seq >> 16)
    52  	b[pos+3] = byte(o.Seq >> 24)
    53  	//binary.LittleEndian.PutUint32(b[pos:pos+4],o.Seq)
    54  	pos += 4
    55  
    56  	b[pos] = byte(o.Ack)
    57  	b[pos+1] = byte(o.Ack >> 8)
    58  	b[pos+2] = byte(o.Ack >> 16)
    59  	b[pos+3] = byte(o.Ack >> 24)
    60  	//binary.LittleEndian.PutUint32(b[pos:pos+4],o.Ack)
    61  	pos += 4
    62  
    63  	return b, nil
    64  }
    65  
    66  func MarshalTcpPacketV2ToBuffer(o *TcpPacket, b []byte) (err error) {
    67  	//timeb,err:=o.Time.MarshalBinary() //13.73%
    68  	//if err!=nil{
    69  	//	return err
    70  	//}
    71  	//timeBSize:=len(timeb)
    72  	srcIpSize := len(o.SrcIp)
    73  	dstIpSize := len(o.DstIp)
    74  	//size:=1+timeBSize+1+srcIpSize+2+1+ dstIpSize +2+4+4
    75  	size := 1 + srcIpSize + 2 + 1 + dstIpSize + 2 + 4 + 4
    76  	if len(b) < size {
    77  		return fmt.Errorf("[MarshalTcpPacketV2ToBuffer] too small buffer")
    78  	}
    79  	pos := 0
    80  	//b[pos] = byte(timeBSize)
    81  	//pos++
    82  	//copy(b[pos:pos+timeBSize],timeb)
    83  	//pos+=timeBSize
    84  
    85  	b[pos] = byte(srcIpSize)
    86  	pos++
    87  	copy(b[pos:pos+srcIpSize], o.SrcIp)
    88  	pos += srcIpSize
    89  
    90  	b[pos] = byte(o.SrcPort)
    91  	b[pos+1] = byte(o.SrcPort >> 8)
    92  	//binary.LittleEndian.PutUint16(b[pos:pos+2],o.SrcPort)
    93  	pos += 2
    94  
    95  	b[pos] = byte(dstIpSize)
    96  	pos++
    97  	copy(b[pos:pos+srcIpSize], o.SrcIp)
    98  	pos += dstIpSize
    99  
   100  	b[pos] = byte(o.DstPort)
   101  	b[pos+1] = byte(o.DstPort >> 8)
   102  	//binary.LittleEndian.PutUint16(b[pos:pos+2],o.DstPort)
   103  	pos += 2
   104  
   105  	b[pos] = byte(o.Seq)
   106  	b[pos+1] = byte(o.Seq >> 8)
   107  	b[pos+2] = byte(o.Seq >> 16)
   108  	b[pos+3] = byte(o.Seq >> 24)
   109  	//binary.LittleEndian.PutUint32(b[pos:pos+4],o.Seq)
   110  	pos += 4
   111  
   112  	b[pos] = byte(o.Ack)
   113  	b[pos+1] = byte(o.Ack >> 8)
   114  	b[pos+2] = byte(o.Ack >> 16)
   115  	b[pos+3] = byte(o.Ack >> 24)
   116  	//binary.LittleEndian.PutUint32(b[pos:pos+4],o.Ack)
   117  	pos += 4
   118  
   119  	return nil
   120  }
   121  
   122  func UnmarshalTcpPacketV2(b []byte) (packet TcpPacket, err error) {
   123  	packet = TcpPacket{} // 13.73%
   124  	pos := 0
   125  	//timeSize:=b[pos]
   126  	//pos++
   127  	//err = packet.Time.UnmarshalBinary(b[pos:pos+int(timeSize)]) //4.39%
   128  	//if err!=nil{
   129  	//	return packet,err
   130  	//}
   131  	//pos+=int(timeSize)
   132  
   133  	sSize := b[pos]
   134  	packet.SrcIp = BytesToString(b[pos : pos+int(sSize)]) //12.48%
   135  	pos += int(sSize)
   136  
   137  	packet.SrcPort = binary.LittleEndian.Uint16(b[pos : pos+2])
   138  	pos += 2
   139  
   140  	sSize = b[pos]
   141  	packet.DstIp = BytesToString(b[pos : pos+int(sSize)])
   142  	pos += int(sSize)
   143  
   144  	packet.DstPort = binary.LittleEndian.Uint16(b[pos : pos+2])
   145  	pos += 2
   146  
   147  	packet.Seq = binary.LittleEndian.Uint32(b[pos : pos+4])
   148  	pos += 4
   149  
   150  	packet.Ack = binary.LittleEndian.Uint32(b[pos : pos+4])
   151  	pos += 4
   152  	return packet, nil
   153  }
   154  
   155  func BytesToString(b []byte) string {
   156  	bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
   157  	sh := reflect.StringHeader{bh.Data, bh.Len}
   158  	return *(*string)(unsafe.Pointer(&sh))
   159  }
   160  
   161  func StringToBytes(s string) []byte {
   162  	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
   163  	bh := reflect.SliceHeader{sh.Data, sh.Len, 0}
   164  	return *(*[]byte)(unsafe.Pointer(&bh))
   165  }
   166  
   167  func BenchmarkKsonV2Marshal(b *testing.B) {
   168  	data := &TcpPacket{
   169  		Time:  time.Now().In(time.UTC),
   170  		SrcIp: "1.2.3.4",
   171  		DstIp: "1.2.3.4",
   172  	}
   173  	total := 0
   174  	buf := make([]byte, 4096)
   175  	b.ResetTimer()
   176  	for i := 0; i < b.N; i++ {
   177  		err := MarshalTcpPacketV2ToBuffer(data, buf)
   178  		if err != nil {
   179  			panic(err)
   180  		}
   181  		//total += len(buf)
   182  	}
   183  	b.SetBytes(int64(total / b.N))
   184  }
   185  
   186  func BenchmarkKsonV2Unmarshal(b *testing.B) {
   187  	data := &TcpPacket{
   188  		Time:  time.Now().In(time.UTC),
   189  		SrcIp: "1.2.3.4",
   190  		DstIp: "1.2.3.4",
   191  	}
   192  	buf, err := MarshalTcpPacketV2(data)
   193  	if err != nil {
   194  		panic(err)
   195  	}
   196  	b.SetBytes(int64(len(buf)))
   197  	b.ResetTimer()
   198  	for i := 0; i < b.N; i++ {
   199  		_, err := UnmarshalTcpPacketV2(buf)
   200  		if err != nil {
   201  			panic(err)
   202  		}
   203  	}
   204  }