jsondb: improve performance of list operation

Since we only need to retrieve the file names, we can use
`(*os.File).Readdirnames` to avoid reading the whole file info for
better performance.

Sample benchmark:

func Benchmark_Readdir(b *testing.B) {
	for i := 0; i < b.N; i++ {
		f, err := os.Open("/")
		if err != nil {
			b.Fatal(err)
		}

		_, err = f.Readdir(-1)
		if err != nil {
			f.Close()
			b.Fatal(err)
		}

		f.Close()
	}
}

func Benchmark_Readdirnames(b *testing.B) {
	for i := 0; i < b.N; i++ {
		f, err := os.Open("/")
		if err != nil {
			b.Fatal(err)
		}

		_, err = f.Readdirnames(-1)
		if err != nil {
			f.Close()
			b.Fatal(err)
		}

		f.Close()
	}
}

goos: linux
goarch: amd64
pkg: github.com/osbuild/osbuild-composer/internal/jsondb
cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
Benchmark_Readdir-16         	   31304	     33551 ns/op	    5638 B/op	      70 allocs/op
Benchmark_Readdirnames-16    	  128443	     12124 ns/op	    1228 B/op	      30 allocs/op
PASS
ok  	github.com/osbuild/osbuild-composer/internal/jsondb	3.098s

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
This commit is contained in:
Eng Zer Jun 2023-06-19 21:40:27 +08:00 committed by Ondřej Budai
parent 47bbe8f0fe
commit 537add3d70

View file

@ -66,14 +66,14 @@ func (db *JSONDatabase) List() ([]string, error) {
}
defer f.Close()
infos, err := f.Readdir(-1)
dirNames, err := f.Readdirnames(-1)
if err != nil {
return nil, err
}
names := make([]string, len(infos))
for i, info := range infos {
names[i] = strings.TrimSuffix(info.Name(), ".json")
names := make([]string, len(dirNames))
for i, name := range dirNames {
names[i] = strings.TrimSuffix(name, ".json")
}
return names, nil