Some perf work

This takes off some time in our benchmark, but we still spend a lot of time
creating the filenames out of the slice and allocating objects.
This commit is contained in:
Carlos Martín Nieto 2017-10-23 14:06:16 +02:00
parent e40cf421a0
commit 1eeddfa291
2 changed files with 22 additions and 15 deletions

View File

@ -12,13 +12,13 @@ import (
// Tree. // Tree.
type ManagedTree struct { type ManagedTree struct {
m map[string]*TreeEntry m map[string]*TreeEntry
l []*TreeEntry l []TreeEntry
} }
func (t *ManagedTree) EntryById(id *Oid) *TreeEntry { func (t *ManagedTree) EntryById(id *Oid) *TreeEntry {
for _, entry := range t.l { for _, entry := range t.l {
if entry.Id.Equal(id) { if entry.Id.Equal(id) {
return entry return &entry
} }
} }
@ -30,7 +30,7 @@ func (t *ManagedTree) EntryByName(filename string) *TreeEntry {
} }
func (t *ManagedTree) EntryByIndex(index uint64) *TreeEntry { func (t *ManagedTree) EntryByIndex(index uint64) *TreeEntry {
return t.l[index] return &t.l[index]
} }
func (t *ManagedTree) EntryCount() uint64 { func (t *ManagedTree) EntryCount() uint64 {
@ -54,8 +54,12 @@ func NewManagedTree(r *Repository, id *Oid) (*ManagedTree, error) {
} }
data := obj.Data() data := obj.Data()
l := make([]*TreeEntry, 0, 8) // var buf bytes.Buffer
m := make(map[string]*TreeEntry) // buf.Grow(len(borrowedData))
// buf.Write(borrowedData)
// data := buf.Bytes()
l := make([]TreeEntry, 0, 24)
var done bool var done bool
for !done { for !done {
@ -74,27 +78,30 @@ func NewManagedTree(r *Repository, id *Oid) (*ManagedTree, error) {
return nil, errors.New("failed to find NUL after filename") return nil, errors.New("failed to find NUL after filename")
} }
var name bytes.Buffer name := string(data[:nulAt])
name.Grow(nulAt)
name.Write(data[:nulAt])
data = data[nulAt+1:] data = data[nulAt+1:]
oid := NewOidFromBytes(data) oid := data[:20]
if len(data) > 20 { if len(data) > 20 {
data = data[20:] data = data[20:]
} else { } else {
done = true done = true
} }
entry := &TreeEntry{ entry := TreeEntry{
Name: name.String(), Name: name,
Id: oid, //Id: Oid(oid),
Type: typeFromMode(mode), Type: typeFromMode(mode),
Filemode: Filemode(mode), Filemode: Filemode(mode),
} }
copy(entry.Id[:], oid)
l = append(l, entry) l = append(l, entry)
m[entry.Name] = entry }
m := make(map[string]*TreeEntry, len(l))
for _, entry := range l {
m[entry.Name] = &entry
} }
// This avoids the runtime from garbage-collecting 'obj' and freeing the // This avoids the runtime from garbage-collecting 'obj' and freeing the

View File

@ -33,7 +33,7 @@ func (t *Tree) AsObject() *Object {
type TreeEntry struct { type TreeEntry struct {
Name string Name string
Id *Oid Id Oid
Type ObjectType Type ObjectType
Filemode Filemode Filemode Filemode
} }
@ -41,7 +41,7 @@ type TreeEntry struct {
func newTreeEntry(entry *C.git_tree_entry) *TreeEntry { func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
return &TreeEntry{ return &TreeEntry{
C.GoString(C.git_tree_entry_name(entry)), C.GoString(C.git_tree_entry_name(entry)),
newOidFromC(C.git_tree_entry_id(entry)), *newOidFromC(C.git_tree_entry_id(entry)),
ObjectType(C.git_tree_entry_type(entry)), ObjectType(C.git_tree_entry_type(entry)),
Filemode(C.git_tree_entry_filemode(entry)), Filemode(C.git_tree_entry_filemode(entry)),
} }