Skip to content

Conversation

@caarlos0
Copy link
Member

@caarlos0 caarlos0 commented Jan 9, 2026

Replace io.Reader-based config loading with direct []byte handling. Remove intermediate Merge wrapper, skip empty files.

name                     old time/op    new time/op    delta
LoadFromConfigPaths-12     52.4µs         53.5µs       +2.0%

name                     old alloc/op   new alloc/op   delta
LoadFromConfigPaths-12     54.7KB         54.5KB       -0.4%

name                     old allocs/op  new allocs/op  delta
LoadFromConfigPaths-12        477            472       -1.0%

basically, go-jsons would read all the readers entirely anyway, so this saves a couple of allocations and simplify things a bit. Also prevents leaving files opened for longer than necessary.

time diff are negligible (noise), it does saves some allocations, the more files the merrier, but in the end it doesn't matter too much. Main thing is closing files early.

Replace io.Reader-based config loading with direct []byte handling.
Remove intermediate Merge wrapper, skip empty files.

name                     old time/op    new time/op    delta
LoadFromConfigPaths-12     52.4µs         53.5µs       +2.0%

name                     old alloc/op   new alloc/op   delta
LoadFromConfigPaths-12     54.7KB         54.5KB       -0.4%

name                     old allocs/op  new allocs/op  delta
LoadFromConfigPaths-12        477            472       -1.0%

Assisted-by: Claude Opus 4.5 via Crush <crush@charm.land>
@caarlos0 caarlos0 self-assigned this Jan 9, 2026
Copilot AI review requested due to automatic review settings January 9, 2026 20:56
@caarlos0 caarlos0 requested a review from a team as a code owner January 9, 2026 20:56
@caarlos0 caarlos0 requested review from aymanbagabas and raphamorim and removed request for a team January 9, 2026 20:56
@caarlos0
Copy link
Member Author

caarlos0 commented Jan 9, 2026

PS: this one would actually be way better allocation wise: #1285

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes configuration loading by replacing io.Reader-based handling with direct []byte operations. The key changes simplify the code by eliminating the intermediate Merge wrapper function and preventing unnecessary file handle retention. Additionally, the PR introduces empty file skipping and adds comprehensive benchmark tests.

  • Removed intermediate Merge wrapper, using jsons.Merge directly
  • Replaced os.Open with os.ReadFile for simpler file handling without explicit Close calls
  • Added logic to skip empty configuration files

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
internal/config/merge.go Removed wrapper function that converted []io.Reader to []byte for jsons.Merge
internal/config/merge_test.go Removed tests for the now-deleted Merge wrapper function
internal/config/load.go Replaced io.Reader-based loading with []byte handling; removed LoadReader; added empty file skip; renamed loadFromReaders to loadFromBytes
internal/config/load_test.go Updated test to use []byte instead of strings.NewReader; renamed test function
internal/config/attribution_migration_test.go Updated test call to use []byte array instead of io.Reader
internal/config/load_bench_test.go Added comprehensive benchmark tests for different config loading scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if os.IsNotExist(err) {
continue
}
return nil, fmt.Errorf("failed to open config file %s: %w", path, err)
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

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

The error message says "failed to open config file" but the code is now using os.ReadFile instead of os.Open. Consider updating the error message to "failed to read config file" for accuracy.

Suggested change
return nil, fmt.Errorf("failed to open config file %s: %w", path, err)
return nil, fmt.Errorf("failed to read config file %s: %w", path, err)

Copilot uses AI. Check for mistakes.
Comment on lines +630 to +632
if len(data) == 0 {
continue
}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

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

The new behavior of skipping empty config files (line 630-632) lacks explicit test coverage. Consider adding a test case in load_test.go that verifies empty files are skipped during config loading, similar to the existing TestConfig_LoadFromBytes test.

Copilot uses AI. Check for mistakes.
data, err := jsons.Merge(configs)
if err != nil {
return nil, fmt.Errorf("failed to merge configuration readers: %w", err)
return nil, err
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

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

The error from jsons.Merge is now returned without additional context. The previous code wrapped it with "failed to merge configuration readers". Consider adding context to help users understand what operation failed when they encounter this error.

Copilot uses AI. Check for mistakes.
return LoadReader(merged)
var config Config
if err := json.Unmarshal(data, &config); err != nil {
return nil, err
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

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

The error from json.Unmarshal is returned without context. Consider wrapping it with additional information to help users understand that the merged configuration failed to parse, similar to how the previous error at line 628 provides context about which config file failed.

Copilot uses AI. Check for mistakes.
@aymanbagabas
Copy link
Member

PS: this one would actually be way better allocation wise: #1285

You mean #1285 is better than this or the other way around?

@caarlos0
Copy link
Member Author

yes, #1285 gets rid of the json merge library - and also gives us better merges, with the other side of the coin being that we'll need to write more code (when adding new config fields, basically)

@kujtimiihoxha
Copy link
Member

yes, #1285 gets rid of the json merge library - and also gives us better merges, with the other side of the coin being that we'll need to write more code (when adding new config fields, basically)

@caarlos0 will merge this one in and probably merge the #1285 later, I need to either way change some stuff in config to support some workflow I want and I can include that PR there.

@kujtimiihoxha kujtimiihoxha merged commit a447f55 into main Jan 12, 2026
22 checks passed
@kujtimiihoxha kujtimiihoxha deleted the config-load branch January 12, 2026 13:24
BrunoKrugel pushed a commit to BrunoKrugel/crush that referenced this pull request Jan 12, 2026
puffitos pushed a commit to puffitos/crush that referenced this pull request Jan 13, 2026
puffitos pushed a commit to puffitos/crush that referenced this pull request Jan 13, 2026
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.

4 participants