mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-31 14:01:56 +00:00
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.
This commit is contained in:
parent
296cc1bca2
commit
807a6b1022
@ -23,7 +23,7 @@ type jobQueue struct {
|
|||||||
type jobQueueEntry struct {
|
type jobQueueEntry struct {
|
||||||
name string
|
name string
|
||||||
size int64
|
size int64
|
||||||
modified time.Time
|
modified int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func newJobQueue() *jobQueue {
|
func newJobQueue() *jobQueue {
|
||||||
@ -34,7 +34,8 @@ func newJobQueue() *jobQueue {
|
|||||||
|
|
||||||
func (q *jobQueue) Push(file string, size int64, modified time.Time) {
|
func (q *jobQueue) Push(file string, size int64, modified time.Time) {
|
||||||
q.mut.Lock()
|
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()
|
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
|
type oldestFirst []jobQueueEntry
|
||||||
|
|
||||||
func (q oldestFirst) Len() int { return len(q) }
|
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] }
|
func (q oldestFirst) Swap(a, b int) { q[a], q[b] = q[b], q[a] }
|
||||||
|
@ -8,6 +8,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -251,16 +252,19 @@ func TestSortByAge(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkJobQueueBump(b *testing.B) {
|
func BenchmarkJobQueueBump(b *testing.B) {
|
||||||
files := genFiles(b.N)
|
files := genFiles(10000)
|
||||||
|
|
||||||
q := newJobQueue()
|
q := newJobQueue()
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
q.Push(f.Name, 0, time.Time{})
|
q.Push(f.Name, 0, time.Time{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rng := rand.New(rand.NewSource(int64(b.N)))
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
q.BringToFront(files[i].Name)
|
r := rng.Intn(len(files))
|
||||||
|
q.BringToFront(files[r].Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user