@@ -37,14 +37,10 @@ func (e *Entity) FindProperty(name string) *PropertyEntry {
3737 return prop
3838}
3939
40- // Wrapping the slice in a struct causes far fewer object allocations for some reason
41- type entrySliceBacker struct {
42- slice []* PropertyEntry
43- }
44-
45- var entrySliceBackerPool sync.Pool = sync.Pool {
40+ var updatedPropIndicesPool = sync.Pool {
4641 New : func () interface {} {
47- return & entrySliceBacker {make ([]* PropertyEntry , 0 , 8 )}
42+ s := make ([]int , 0 , 8 )
43+ return & s
4844 },
4945}
5046
@@ -53,21 +49,20 @@ var entrySliceBackerPool sync.Pool = sync.Pool{
5349func (e * Entity ) ApplyUpdate (reader * bit.BitReader ) {
5450 idx := - 1
5551 newWay := reader .ReadBit ()
56- backer := entrySliceBackerPool .Get ().(* entrySliceBacker )
52+ updatedPropIndices := updatedPropIndicesPool .Get ().(* [] int )
5753
58- // TODO: Use index slice instead?
5954 for idx = readFieldIndex (reader , idx , newWay ); idx != - 1 ; idx = readFieldIndex (reader , idx , newWay ) {
60- backer . slice = append (backer . slice , & e . props [ idx ] )
55+ * updatedPropIndices = append (* updatedPropIndices , idx )
6156 }
6257
63- for _ , prop := range backer . slice {
64- prop . FirePropertyUpdate (propDecoder .decodeProp (prop .entry , reader ))
58+ for _ , idx := range * updatedPropIndices {
59+ e . props [ idx ]. FirePropertyUpdate (propDecoder .decodeProp (e . props [ idx ] .entry , reader ))
6560 }
6661
67- // Reset to 0 length before pooling
68- backer . slice = backer . slice [:0 ]
62+ // Reset length to 0 before pooling
63+ * updatedPropIndices = ( * updatedPropIndices ) [:0 ]
6964 // Defer has quite the overhead so we just fill the pool here
70- entrySliceBackerPool .Put (backer )
65+ updatedPropIndicesPool .Put (updatedPropIndices )
7166}
7267
7368func readFieldIndex (reader * bit.BitReader , lastIndex int , newWay bool ) int {
0 commit comments