test: add benchmarks for glob cache performance#2881
Conversation
Add Issue go-task#2853 benchmarks comparing checksum, timestamp, and uncached tasks across many-small and few-large sparse YAML source sets. Baseline on Intel i7-14700K, go test -run '^$' -bench 'BenchmarkIssue2853.*SparseYAMLFiles' -benchtime=3x -count=3 ./ Many small sparse YAML files (20,000 x 5 bytes): checksum 440-451 ms/op, timestamp 140-148 ms/op, none 1.1-1.3 ms/op. Few large sparse YAML files (4 x 128 MiB): checksum 60-61 ms/op, timestamp 213-239 us/op, none 1.1-1.3 ms/op. Sparse files avoid bulk data writes while preserving logical file size for checksum/timestamp comparisons.
|
I suggest this benchmark for tracking speed for many small, and few large globs. |
|
Would/could you add an OS Native benchmark too, using Having the test profile code might also be useful. This function in particular: Edit: Another point of reference (in addition to mtime) would be to generate a Makefile and run that over the files too. |
| @@ -0,0 +1,155 @@ | |||
| package task_test | |||
There was a problem hiding this comment.
Need a build tag here.
//go:build fsbench
// +build fsbench
|
@Napolitain If you want to try your luck and improve the performance, I "Asked AI" to make the code more efficient, and then again to see if the duplicate calls to os.Stat() could be improved. There is not much code there, so profiling or trial and error should find some improvement. https://github.com/go-task/task/blob/main/internal/fingerprint/sources_timestamp.go Strategy: globbing improvedStrategy: os.Stat calls improved |
Add an OS-native mtime reference point for the Issue go-task#2853 filesystem benchmarks. The reference walks the same sparse YAML source tree with filepath.WalkDir, stats YAML files through DirEntry.Info, and compares mtimes against a generated output file. The benchmark is available under the fsbench build tag alongside the Task checksum, timestamp, and uncached cases.
addressed in ec19102 if I understood that part correctly. |
|
I profiled task when running your benchmarks. It seems like the timestamp itself might not be the only issue. There is a lot of templater action ... but I can't understand why. |
I think we should merge the test only, then create follow up PR for trying to solve the performance issue and over alloc. This way, maintainers can easily revert a performance PR if they judge it to be problematic without removing the benchmark itself (which shouldn't be harmful). |
It might simply be the test data generation. To do a clean profiling it might be necessary to rework that a little. |
I dont think test data generation is within timed test. |
|
my results |
Rename the fsbench benchmark entry points from Issue-2853-specific names to BenchmarkManySmallFiles and BenchmarkFewLargeFiles. The benchmark output is now easier to scan while the PR and commit history still carry the issue context. Helper and constant names were updated to match; benchmark behavior is unchanged.
|
It will be necessary to collect profiling data to figure out a good implementation (using pperf) so I assume it will be necessary to isolate the data generation part of the test. In any case, you might try this in your MTime comparison. func ReadDir(name string) ([]DirEntry, error) It should be possible to retrieve all FileInfo for files in a directory in one system call, rather than 20.000 calls to os.Stat(). |
|
@timrulebosch @trulede please check #2883 |
|
As well as #2884. |
I think |
Add Issue #2853 benchmarks comparing checksum, timestamp, and uncached tasks across many-small and few-large sparse source sets.
In my opinion, it looks like there are too many allocations and there must be inefficiencies in the many-small sources scenario.
The MB/s is not a IO rate (timestamp doesn't do IO). More like, a throughput comparison.