Skip to content

perf: avoid eager fingerprint variable evaluation#2883

Open
Napolitain wants to merge 2 commits into
go-task:mainfrom
Napolitain:issue-2853-lazy-fingerprint-vars
Open

perf: avoid eager fingerprint variable evaluation#2883
Napolitain wants to merge 2 commits into
go-task:mainfrom
Napolitain:issue-2853-lazy-fingerprint-vars

Conversation

@Napolitain

@Napolitain Napolitain commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

This is a stacked optimization PR on top of the filesystem benchmark work in #2881. Please review or merge #2881 first; this branch intentionally depends on those benchmarks so the performance impact can be evaluated with the same many-small and few-large fixtures. In this way we can also easily revert a commit if needed, without affecting the test (which is naturally harmless).

That PR avoids duplicate fingerprint evaluation during task compilation

(I think, if I put the base as my branch, then I can't switch of origin)

BenchmarkManySmallFiles/checksum-28                    3         139978116 ns/op           0.71 MB/s             0.09537 source_MiB/op     20000 source_files/op      679207408 B/op    248202 allocs/op
BenchmarkManySmallFiles/timestamp-28                   3          42650460 ns/op           2.34 MB/s             0.09537 source_MiB/op     20000 source_files/op      25159722 B/op     188222 allocs/op
BenchmarkManySmallFiles/native-mtime-28                3          18077746 ns/op           5.53 MB/s             0.09537 source_MiB/op     20000 source_files/op      11558392 B/op     123036 allocs/op
BenchmarkManySmallFiles/none-28                        3            701787 ns/op         2598624 B/op       3193 allocs/op

BenchmarkFewLargeFiles/checksum-28                     3          19877230 ns/op        27009.34 MB/s          512.0 source_MiB/op            4.000 source_files/op     517832 B/op       1717 allocs/op
BenchmarkFewLargeFiles/timestamp-28                    3            147128 ns/op        3648997.44 MB/s        512.0 source_MiB/op            4.000 source_files/op     261288 B/op       1730 allocs/op
BenchmarkFewLargeFiles/native-mtime-28                 3             17511 ns/op        30659066.42 MB/s               512.0 source_MiB/op             4.000 source_files/op      4701 B/op         44 allocs/op
BenchmarkFewLargeFiles/none-28                         3            967514 ns/op         2599981 B/op       3193 allocs/op

@andreynering andreynering left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Napolitain

I added a comment below. Can you take a look + rebase with main?

Comment thread variables.go Outdated
return &new, nil
}

func taskReferencesFingerprintVar(t *ast.Task, kind string) bool {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a lot a new functions in this file. I propose to move all of them to its own file in the taskfile/ast package. What do you think?

Maybe taskfile/ask/fingerprint.go

@Napolitain Napolitain Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I moved them to taskfile/ast/fingerprint.go.

@andreynering andreynering mentioned this pull request Jul 11, 2026
@Napolitain Napolitain force-pushed the issue-2853-lazy-fingerprint-vars branch from bd7b227 to 1452a80 Compare July 12, 2026 01:16
@Napolitain Napolitain marked this pull request as ready for review July 12, 2026 02:04
Only compute CHECKSUM or TIMESTAMP template variables when the raw task references the corresponding variable in commands, dependencies, preconditions, or status. This keeps the up-to-date source check unchanged while avoiding a duplicate fingerprint pass for tasks that only use sources and generates caching.

Against current main with 20,000 tiny files, checksum improves from 440-445 ms/op to 136-145 ms/op and timestamp from 125-136 ms/op to 44-46 ms/op. Allocations fall from about 742k to 248k for checksum and from about 562k to 188k for timestamp.

Verification: go test ./...; golangci-lint run
Move fingerprint-variable reference traversal out of task compilation and into the taskfile AST package as Task.ReferencesFingerprintVar. Keep traversal helpers private and add focused coverage for commands, dependencies, preconditions, status, loops, matrices, nested variables, and nil entries.
@Napolitain Napolitain force-pushed the issue-2853-lazy-fingerprint-vars branch from 1452a80 to 5329fdb Compare July 12, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants