Skip to content

Commit 45b0742

Browse files
Optimize string accumulation in ExtractTopology to avoid intermediate allocations
Co-authored-by: xkilldash9x <223238109+xkilldash9x@users.noreply.github.com>
1 parent 932ae11 commit 45b0742

2 files changed

Lines changed: 58 additions & 10 deletions

File tree

pkg/analysis/topology/topology.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -253,16 +253,7 @@ func ExtractTopology(fn *ssa.Function) *FunctionTopology {
253253
return t.StringLiterals[i] < t.StringLiterals[j]
254254
})
255255

256-
totalSize := 0
257-
for _, s := range t.StringLiterals {
258-
// With StringVal, we no longer need to strip quotes manually, but we keep logic simple
259-
totalSize += len(s)
260-
}
261-
262-
dataAccumulator := make([]byte, 0, totalSize)
263-
for _, s := range t.StringLiterals {
264-
dataAccumulator = append(dataAccumulator, []byte(s)...)
265-
}
256+
dataAccumulator := flattenStringLiterals(t.StringLiterals)
266257

267258
if len(dataAccumulator) > 0 {
268259
t.EntropyScore = CalculateEntropy(dataAccumulator)
@@ -571,3 +562,17 @@ func TopologyFingerprint(t *FunctionTopology) string {
571562

572563
return fmt.Sprintf("L%dB%dI%d[%s]", t.LoopCount, t.BranchCount, t.InstrCount, callStr)
573564
}
565+
566+
func flattenStringLiterals(literals []string) []byte {
567+
totalSize := 0
568+
for _, s := range literals {
569+
// With StringVal, we no longer need to strip quotes manually, but we keep logic simple
570+
totalSize += len(s)
571+
}
572+
573+
dataAccumulator := make([]byte, 0, totalSize)
574+
for _, s := range literals {
575+
dataAccumulator = append(dataAccumulator, s...)
576+
}
577+
return dataAccumulator
578+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package topology
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
)
7+
8+
func TestFlattenStringLiterals(t *testing.T) {
9+
literals := []string{
10+
"hello",
11+
"world",
12+
"",
13+
"foo",
14+
"bar",
15+
"baz",
16+
}
17+
expected := []byte("helloworldfoobarbaz")
18+
19+
result := flattenStringLiterals(literals)
20+
21+
if !bytes.Equal(result, expected) {
22+
t.Errorf("expected %q, got %q", expected, result)
23+
}
24+
}
25+
26+
func BenchmarkFlattenStringLiterals(b *testing.B) {
27+
baseLiterals := []string{
28+
"some string",
29+
"another string",
30+
"yet another string",
31+
"long string data here to make it worthwile",
32+
"short",
33+
}
34+
var literals []string
35+
for i := 0; i < 2000; i++ {
36+
literals = append(literals, baseLiterals...)
37+
}
38+
39+
b.ResetTimer()
40+
for i := 0; i < b.N; i++ {
41+
_ = flattenStringLiterals(literals)
42+
}
43+
}

0 commit comments

Comments
 (0)