|
1 | 1 | package encoder |
2 | 2 |
|
3 | | -import "github.com/IncSW/go-bencode/internal" |
| 3 | +import ( |
| 4 | + "sort" |
| 5 | + "sync" |
| 6 | + |
| 7 | + "github.com/IncSW/go-bencode/internal" |
| 8 | +) |
| 9 | + |
| 10 | +const stringsArrayLen = 20 |
| 11 | + |
| 12 | +var stringsArrayPool = sync.Pool{ |
| 13 | + New: func() interface{} { |
| 14 | + return &[stringsArrayLen]string{} |
| 15 | + }, |
| 16 | +} |
| 17 | + |
| 18 | +func sortStrings(ss []string) { |
| 19 | + if len(ss) <= stringsArrayLen { |
| 20 | + for i := 1; i < len(ss); i++ { |
| 21 | + for j := i; j > 0; j-- { |
| 22 | + if ss[j] >= ss[j-1] { |
| 23 | + break |
| 24 | + } |
| 25 | + ss[j], ss[j-1] = ss[j-1], ss[j] |
| 26 | + } |
| 27 | + } |
| 28 | + } else { |
| 29 | + sort.Strings(ss) |
| 30 | + } |
| 31 | +} |
4 | 32 |
|
5 | 33 | //go:nosplit |
6 | 34 | func (e *Encoder) encodeDictionary(data map[string]interface{}) error { |
7 | 35 | e.grow(1) |
8 | 36 | e.writeByte('d') |
9 | | - keys := make([]string, 0, len(data)) |
| 37 | + var keys []string |
| 38 | + if len(data) <= stringsArrayLen { |
| 39 | + stringsArray := stringsArrayPool.Get().(*[stringsArrayLen]string) |
| 40 | + defer stringsArrayPool.Put(stringsArray) |
| 41 | + keys = stringsArray[:0:len(data)] |
| 42 | + } else { |
| 43 | + keys = make([]string, 0, len(data)) |
| 44 | + } |
10 | 45 | for key, _ := range data { |
11 | 46 | keys = append(keys, key) |
12 | 47 | } |
13 | | - internal.SortStrings(keys) |
| 48 | + sortStrings(keys) |
14 | 49 | for _, key := range keys { |
15 | 50 | e.encodeBytes(internal.S2B(key)) |
16 | 51 | err := e.encode(data[key]) |
|
0 commit comments