瀏覽代碼

lib/model: Optimize jobQueue performance and memory use (#8023)

By truncating time.Time to an int64 nanosecond count, we lose the
ability to precisely order timestamps before 1678 or after 2262, but we
gain (linux/amd64, Go 1.17.1):

name                      old time/op    new time/op    delta
JobQueuePushPopDone10k-8    2.85ms ± 5%    2.29ms ± 2%  -19.80%  (p=0.000 n=20+18)
JobQueueBump-8              34.0µs ± 1%    29.8µs ± 1%  -12.35%  (p=0.000 n=19+19)

name                      old alloc/op   new alloc/op   delta
JobQueuePushPopDone10k-8    2.56MB ± 0%    1.76MB ± 0%  -31.31%  (p=0.000 n=18+13)

name                      old allocs/op  new allocs/op  delta
JobQueuePushPopDone10k-8      23.0 ± 0%      23.0 ± 0%     ~     (all equal)

Results for BenchmarkJobQueueBump are with the fixed version, which no
longer depends on b.N for the amount of work performed. rand.Rand.Intn
is cheap at ~10ns per iteration.
greatroar 4 年之前
父節點
當前提交
807a6b1022
共有 2 個文件被更改,包括 10 次插入5 次删除
  1. 4 3
      lib/model/queue.go
  2. 6 2
      lib/model/queue_test.go

+ 4 - 3
lib/model/queue.go

@@ -23,7 +23,7 @@ type jobQueue struct {
 type jobQueueEntry struct {
 	name     string
 	size     int64
-	modified time.Time
+	modified int64
 }
 
 func newJobQueue() *jobQueue {
@@ -34,7 +34,8 @@ func newJobQueue() *jobQueue {
 
 func (q *jobQueue) Push(file string, size int64, modified time.Time) {
 	q.mut.Lock()
-	q.queued = append(q.queued, jobQueueEntry{file, size, modified})
+	// The range of UnixNano covers a range of reasonable timestamps.
+	q.queued = append(q.queued, jobQueueEntry{file, size, modified.UnixNano()})
 	q.mut.Unlock()
 }
 
@@ -191,5 +192,5 @@ func (q smallestFirst) Swap(a, b int)      { q[a], q[b] = q[b], q[a] }
 type oldestFirst []jobQueueEntry
 
 func (q oldestFirst) Len() int           { return len(q) }
-func (q oldestFirst) Less(a, b int) bool { return q[a].modified.Before(q[b].modified) }
+func (q oldestFirst) Less(a, b int) bool { return q[a].modified < q[b].modified }
 func (q oldestFirst) Swap(a, b int)      { q[a], q[b] = q[b], q[a] }

+ 6 - 2
lib/model/queue_test.go

@@ -8,6 +8,7 @@ package model
 
 import (
 	"fmt"
+	"math/rand"
 	"testing"
 	"time"
 
@@ -251,16 +252,19 @@ func TestSortByAge(t *testing.T) {
 }
 
 func BenchmarkJobQueueBump(b *testing.B) {
-	files := genFiles(b.N)
+	files := genFiles(10000)
 
 	q := newJobQueue()
 	for _, f := range files {
 		q.Push(f.Name, 0, time.Time{})
 	}
 
+	rng := rand.New(rand.NewSource(int64(b.N)))
+
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		q.BringToFront(files[i].Name)
+		r := rng.Intn(len(files))
+		q.BringToFront(files[r].Name)
 	}
 }