mirror of
https://github.com/restic/restic.git
synced 2025-12-04 02:41:52 +00:00
internal/restic: Don't allocate in Tree.Insert
name old time/op new time/op delta BuildTree-8 34.6µs ± 4% 7.0µs ± 3% -79.68% (p=0.000 n=18+19) name old alloc/op new alloc/op delta BuildTree-8 34.0kB ± 0% 0.9kB ± 0% -97.37% (p=0.000 n=20+20) name old allocs/op new allocs/op delta BuildTree-8 108 ± 0% 1 ± 0% -99.07% (p=0.000 n=20+20)
This commit is contained in:
@@ -14,10 +14,10 @@ type Tree struct {
|
||||
Nodes []*Node `json:"nodes"`
|
||||
}
|
||||
|
||||
// NewTree creates a new tree object.
|
||||
func NewTree() *Tree {
|
||||
// NewTree creates a new tree object with the given initial capacity.
|
||||
func NewTree(capacity int) *Tree {
|
||||
return &Tree{
|
||||
Nodes: []*Node{},
|
||||
Nodes: make([]*Node, 0, capacity),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ func (t *Tree) Insert(node *Node) error {
|
||||
return errors.Errorf("node %q already present", node.Name)
|
||||
}
|
||||
|
||||
// https://code.google.com/p/go-wiki/wiki/SliceTricks
|
||||
t.Nodes = append(t.Nodes, &Node{})
|
||||
// https://github.com/golang/go/wiki/SliceTricks
|
||||
t.Nodes = append(t.Nodes, nil)
|
||||
copy(t.Nodes[pos+1:], t.Nodes[pos:])
|
||||
t.Nodes[pos] = node
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/repository"
|
||||
@@ -98,7 +99,7 @@ func TestLoadTree(t *testing.T) {
|
||||
defer cleanup()
|
||||
|
||||
// save tree
|
||||
tree := restic.NewTree()
|
||||
tree := restic.NewTree(0)
|
||||
id, err := repo.SaveTree(context.TODO(), tree)
|
||||
rtest.OK(t, err)
|
||||
|
||||
@@ -113,3 +114,24 @@ func TestLoadTree(t *testing.T) {
|
||||
"trees are not equal: want %v, got %v",
|
||||
tree, tree2)
|
||||
}
|
||||
|
||||
func BenchmarkBuildTree(b *testing.B) {
|
||||
const size = 100 // Directories of this size are not uncommon.
|
||||
|
||||
nodes := make([]restic.Node, size)
|
||||
for i := range nodes {
|
||||
// Archiver.SaveTree inputs in sorted order, so do that here too.
|
||||
nodes[i].Name = strconv.Itoa(i)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
t := restic.NewTree(size)
|
||||
|
||||
for i := range nodes {
|
||||
_ = t.Insert(&nodes[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user