-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pkg/stanza] Introduce batching logs in File consumer #36663
[pkg/stanza] Introduce batching logs in File consumer #36663
Conversation
But send each token of the batch individually via `emit`.
But still emit each Entry individually into the Stanza pipeline
The File input's `emitBatch` function now calls `ProcessBatch` instead of `Process`. The added `ProcessBatch` method will make each Stanza operator capable of accepting a batch of entries. At this stage, all the implementations of `ProcessBatch` just call `Process` in a loop.
…f `[]entry.Entry` According to testing, this results in 7-10% performance improvement.
Instead of adding each entry in a batch separately to the LogEmitter's buffer, add the whole batch in one operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the performance impact of these changes?
err = r.emitFunc(ctx, emit.NewToken(token, r.FileAttributes)) | ||
if err != nil { | ||
r.set.Logger.Error("failed to process token", zap.Error(err)) | ||
tokens = append(tokens, emit.NewToken(copyBody(token), copyAttributes(r.FileAttributes))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What specifically introduces a need to make copies of the body and attributes?
It seems like a lot of overhead - are we sure it's necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without copying, for each token in the tokens
collection, its Body would point to the same place in memory, specifically the Decoder's decodeBuffer.
This isn't a problem when the Reader emits each token before creating a new token, as the token's Body is copied in the emit
function (specifically in the toBody function - the conversion from []byte
to string
copies the underlying array).
Similar with the attributes, the reader::FileAttributes
map would be reused by all tokens if not copied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding correctly then, we're just making the copies in a different place, so this does not introduce new work into the hot path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid it does introduce new work.
How I believe this worked before this change:
- Every time a new token is read from the file, it's placed in the same area in memory - the Decoder's decodeBuffer.
- A pointer to that place in memory is passed to the
emit
function - The
emit
function reads the bytes and creates a newEntry
, copying the bytes into a new area in memory.
How this works after this change:
- Every time a new token is read from the file, it's placed in the same area in memory - the Decoder's decodeBuffer.
- In the Reader's
readContent
function, a batch of tokens is accumulated before calling theemit
function, so the bytes fromdecodeBuffer
need to be copied into a new area in memory for every new token - the accumulated slice of tokens is passed to the
emit
function, which creates a new Entry for every Token, copying the bytes for the second time.
func (i *Input) emit(ctx context.Context, token emit.Token) error { | ||
if len(token.Body) == 0 { | ||
return nil | ||
func (i *Input) emitBatch(ctx context.Context, tokens []emit.Token) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is in the hot path, we might be better off flattening these functions. It seems like a lot of extra error checking and wrapping, where we really just need to put a loop around what was already there, switch from return to append err + continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have inlined the convertToken
function in de66483. Should I inline the convertTokens
function as well?
func (p *Parser) ProcessBatch(ctx context.Context, entries []*entry.Entry) error { | ||
var errs []error | ||
for i := range entries { | ||
errs = append(errs, p.Process(ctx, entries[i])) | ||
} | ||
return errors.Join(errs...) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this exactly the same for all parsers and transformers? If so, can we move it to helper/transformer.go
, where one implementation can be inherited by all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Riiiiight, this probably makes a lot of sense 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh but wait, the ProcessBatch
method calls the Process
method, and Go does not support method overriding, so it will always call the Process
method of the helper.TransformerOperator
struct, right? Is there a simple way around it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. We might not be able to fully eliminate the need for a ProcessBatch
implementation in each operator, but I think at least the implementation details can be consolidated. Same idea as ParseWith
here.
// transformer.go
type ProcessFunc func(context.Context, []*entry.Entry) error
func ProcessBatchWith(ctx context.Context, entries []*entry.Entry, f ProcessFunc) error {
var errs []error
for i := range entries {
errs = append(errs, f(ctx, entries[i]))
}
return errors.Join(errs...)
}
// each implemenation of Transformer
func (p *Parser) ProcessBatch(ctx context.Context, entries []*entry.Entry) error {
return p.ProcessBatchWith(ctx, entries, p.Process)
}
Even though the implementation of ProcessBatch
is pretty simple, I still think it's worth consolidating because any changes in the future could easily be made inconsistently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented in d8704ab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I just realized I only updated transformers and missed parsers in the above commit. Added parsers in 5734fcc.
This should be functionally the same. Hopefully this flow is easier to follow, avoiding a `break` statement.
Do we have a benchmark or benchmarks that we can use to evaluate the net effect of these changes? A lot of the changes appear to have subtle implications so it's difficult to decide if they are worth it or not without some measurements. |
I ran the EndToEnd benchmark (not sure how relevant it is) and the "end to end" test collecting 1 GB of logs from a single file with the collector binary. See below. BenchmarkEndToEndpkg/stanza/adapter/BenchmarkEndToEnd$ go test -run=xxx -bench=EndToEnd
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/adapter
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
BenchmarkEndToEnd/workerCount=1,maxBatchSize=1,flushInterval=10ms-20 2 733116691 ns/op 460448128 B/op 8800782 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=1,flushInterval=100ms-20 2 647384276 ns/op 460445164 B/op 8800702 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=10,flushInterval=10ms-20 2 600991822 ns/op 382361976 B/op 7020680 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=10,flushInterval=100ms-20 2 604421607 ns/op 382354476 B/op 7020603 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=100,flushInterval=10ms-20 2 551094092 ns/op 347132024 B/op 6206621 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=100,flushInterval=100ms-20 2 558686398 ns/op 347128024 B/op 6206598 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=1000,flushInterval=10ms-20 2 541430882 ns/op 343303492 B/op 6112393 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=1000,flushInterval=100ms-20 2 522679270 ns/op 343306200 B/op 6112372 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=10000,flushInterval=10ms-20 2 543155004 ns/op 344406224 B/op 6101974 allocs/op
BenchmarkEndToEnd/workerCount=1,maxBatchSize=10000,flushInterval=100ms-20 2 557043344 ns/op 344405516 B/op 6101967 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=1,flushInterval=10ms-20 2 695154474 ns/op 460446040 B/op 8800736 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=1,flushInterval=100ms-20 2 654490082 ns/op 460444880 B/op 8800742 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=10,flushInterval=10ms-20 2 700169062 ns/op 382358900 B/op 7020720 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=10,flushInterval=100ms-20 2 568586705 ns/op 382354560 B/op 7020616 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=100,flushInterval=10ms-20 2 585962324 ns/op 347131136 B/op 6206675 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=100,flushInterval=100ms-20 2 537941018 ns/op 347125700 B/op 6206561 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=1000,flushInterval=10ms-20 2 529003978 ns/op 343313384 B/op 6112433 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=1000,flushInterval=100ms-20 2 533420602 ns/op 343308764 B/op 6112397 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=10000,flushInterval=10ms-20 2 520374890 ns/op 344423928 B/op 6102022 allocs/op
BenchmarkEndToEnd/workerCount=2,maxBatchSize=10000,flushInterval=100ms-20 2 524670569 ns/op 344409080 B/op 6101958 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=1,flushInterval=10ms-20 2 729801709 ns/op 460443916 B/op 8800771 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=1,flushInterval=100ms-20 2 695331941 ns/op 460445152 B/op 8800753 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=10,flushInterval=10ms-20 2 609127970 ns/op 382356496 B/op 7020632 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=10,flushInterval=100ms-20 2 561177946 ns/op 382353248 B/op 7020594 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=100,flushInterval=10ms-20 2 580258299 ns/op 347130192 B/op 6206621 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=100,flushInterval=100ms-20 2 540122238 ns/op 347130740 B/op 6206614 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=1000,flushInterval=10ms-20 3 490890373 ns/op 343297152 B/op 6112335 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=1000,flushInterval=100ms-20 2 516348068 ns/op 343304052 B/op 6112370 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=10000,flushInterval=10ms-20 2 521940200 ns/op 344406800 B/op 6101944 allocs/op
BenchmarkEndToEnd/workerCount=4,maxBatchSize=10000,flushInterval=100ms-20 2 540817798 ns/op 344405140 B/op 6101957 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=1,flushInterval=10ms-20 2 684520518 ns/op 460444084 B/op 8800734 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=1,flushInterval=100ms-20 2 657656100 ns/op 460443584 B/op 8800704 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=10,flushInterval=10ms-20 2 589294887 ns/op 382353692 B/op 7020618 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=10,flushInterval=100ms-20 2 590353082 ns/op 382354828 B/op 7020627 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=100,flushInterval=10ms-20 2 520960143 ns/op 347128612 B/op 6206573 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=100,flushInterval=100ms-20 2 519195290 ns/op 347129496 B/op 6206587 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=1000,flushInterval=10ms-20 2 557338458 ns/op 343316852 B/op 6112457 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=1000,flushInterval=100ms-20 2 526733440 ns/op 343303436 B/op 6112382 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=10000,flushInterval=10ms-20 2 553058060 ns/op 344406392 B/op 6101964 allocs/op
BenchmarkEndToEnd/workerCount=8,maxBatchSize=10000,flushInterval=100ms-20 2 544634770 ns/op 344406668 B/op 6101979 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=1,flushInterval=10ms-20 2 692173162 ns/op 460445540 B/op 8800773 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=1,flushInterval=100ms-20 2 691081284 ns/op 460443676 B/op 8800737 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=10,flushInterval=10ms-20 2 613109702 ns/op 382355700 B/op 7020641 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=10,flushInterval=100ms-20 2 590538412 ns/op 382359592 B/op 7020622 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=100,flushInterval=10ms-20 2 567399749 ns/op 347130360 B/op 6206644 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=100,flushInterval=100ms-20 2 530738212 ns/op 347125680 B/op 6206576 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=1000,flushInterval=10ms-20 2 537735602 ns/op 343303236 B/op 6112361 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=1000,flushInterval=100ms-20 2 513183656 ns/op 343302976 B/op 6112356 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=10000,flushInterval=10ms-20 2 520426649 ns/op 344404100 B/op 6101938 allocs/op
BenchmarkEndToEnd/workerCount=16,maxBatchSize=10000,flushInterval=100ms-20 2 501402028 ns/op 344402404 B/op 6101928 allocs/op Read 1 GB log fileI ran the "end-to-end" test collecting 1 GB of logs from a single file, as described in #35454 (comment). This (somewhat surprisingly to me) seems to result in a significant performance improvement of about 15%. I ran the tests on my laptop interchangeably, and consistently the main branch collector took 18 seconds to collect all logs, while the batching one took 15 seconds. main-1=== Step 0: 2024-12-16T15:46:55,431446156+01:00
=== Step 1: 2024-12-16T15:46:57,776110136+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 580086
=== Step 2: 2024-12-16T15:46:58,795399607+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.51749e+06
=== Step 3: 2024-12-16T15:46:59,811430467+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 2.525834e+06
=== Step 4: 2024-12-16T15:47:00,826117615+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 3.51771e+06
=== Step 5: 2024-12-16T15:47:01,837294131+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 4.494632e+06
=== Step 6: 2024-12-16T15:47:02,851706243+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 5.503646e+06
=== Step 7: 2024-12-16T15:47:03,867007622+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 6.465843e+06
=== Step 8: 2024-12-16T15:47:04,880762477+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 7.484097e+06
=== Step 9: 2024-12-16T15:47:05,896817941+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 8.34754e+06
=== Step 10: 2024-12-16T15:47:06,918197128+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 9.190601e+06
=== Step 11: 2024-12-16T15:47:07,947497979+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.0064757e+07
=== Step 12: 2024-12-16T15:47:08,970509380+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.093098e+07
=== Step 13: 2024-12-16T15:47:10,006788214+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.1763265e+07
=== Step 14: 2024-12-16T15:47:11,031971467+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.2743549e+07
=== Step 15: 2024-12-16T15:47:12,048653620+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.3799651e+07
=== Step 16: 2024-12-16T15:47:13,061609270+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.4748804e+07
=== Step 17: 2024-12-16T15:47:14,078500681+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.5801047e+07
=== Step 18: 2024-12-16T15:47:15,101722837+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="19ae092a-e6ce-4e2e-8e41-b429a8baa599",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.6519105e+07 main-2=== Step 0: 2024-12-16T15:49:59,937734237+01:00
=== Step 1: 2024-12-16T15:50:00,960695129+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 675923
=== Step 2: 2024-12-16T15:50:01,974959315+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.613065e+06
=== Step 3: 2024-12-16T15:50:02,988684935+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 2.594632e+06
=== Step 4: 2024-12-16T15:50:04,002396877+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 3.626522e+06
=== Step 5: 2024-12-16T15:50:05,015851940+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 4.649102e+06
=== Step 6: 2024-12-16T15:50:06,031987112+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 5.65826e+06
=== Step 7: 2024-12-16T15:50:07,050476545+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 6.652504e+06
=== Step 8: 2024-12-16T15:50:08,069014012+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 7.601671e+06
=== Step 9: 2024-12-16T15:50:09,084814115+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 8.559654e+06
=== Step 10: 2024-12-16T15:50:10,098834674+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 9.47875e+06
=== Step 11: 2024-12-16T15:50:11,115570101+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.0519824e+07
=== Step 12: 2024-12-16T15:50:12,128264343+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.1482479e+07
=== Step 13: 2024-12-16T15:50:13,146768132+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.2395424e+07
=== Step 14: 2024-12-16T15:50:14,163070435+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.341538e+07
=== Step 15: 2024-12-16T15:50:15,179260462+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.4367245e+07
=== Step 16: 2024-12-16T15:50:16,194354312+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.5339147e+07
=== Step 17: 2024-12-16T15:50:17,219358900+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.6343188e+07
=== Step 18: 2024-12-16T15:50:18,236216987+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="60b56197-0e4c-4db9-b9ed-7243520643c1",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.6519105e+07 main-3=== Step 0: 2024-12-16T15:51:47,004466315+01:00
=== Step 1: 2024-12-16T15:51:48,028078945+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 718363
=== Step 2: 2024-12-16T15:51:49,049324584+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.566481e+06
=== Step 3: 2024-12-16T15:51:50,065647473+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 2.723456e+06
=== Step 4: 2024-12-16T15:51:51,089223968+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 3.659562e+06
=== Step 5: 2024-12-16T15:51:52,109708158+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 4.67665e+06
=== Step 6: 2024-12-16T15:51:53,127121621+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 5.788852e+06
=== Step 7: 2024-12-16T15:51:54,140868674+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 6.818451e+06
=== Step 8: 2024-12-16T15:51:55,157193263+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 7.739786e+06
=== Step 9: 2024-12-16T15:51:56,170706945+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 8.769256e+06
=== Step 10: 2024-12-16T15:51:57,190322380+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 9.753002e+06
=== Step 11: 2024-12-16T15:51:58,206357895+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.068764e+07
=== Step 12: 2024-12-16T15:51:59,234101493+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.167782e+07
=== Step 13: 2024-12-16T15:52:00,250850487+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.2714644e+07
=== Step 14: 2024-12-16T15:52:01,265582713+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.3643248e+07
=== Step 15: 2024-12-16T15:52:02,276497572+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.4622953e+07
=== Step 16: 2024-12-16T15:52:03,295299153+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.5473991e+07
=== Step 17: 2024-12-16T15:52:04,308069522+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.6489661e+07
=== Step 18: 2024-12-16T15:52:05,325366799+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="ccfbbd7f-23d8-4ed3-8e67-10121297c203",service_name="otelcontribcol",service_version="0.115.0-dev",transport=""} 1.6519105e+07 batching-1=== Step 0: 2024-12-16T15:49:25,451767918+01:00
=== Step 1: 2024-12-16T15:49:26,473595098+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 757945
=== Step 2: 2024-12-16T15:49:27,489701267+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.744846e+06
=== Step 3: 2024-12-16T15:49:28,502907791+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 2.938626e+06
=== Step 4: 2024-12-16T15:49:29,518975110+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 4.047107e+06
=== Step 5: 2024-12-16T15:49:30,541134228+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 5.224338e+06
=== Step 6: 2024-12-16T15:49:31,563921043+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 6.338091e+06
=== Step 7: 2024-12-16T15:49:32,576716675+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 7.521036e+06
=== Step 8: 2024-12-16T15:49:33,596550216+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 8.649884e+06
=== Step 9: 2024-12-16T15:49:34,620456460+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 9.814609e+06
=== Step 10: 2024-12-16T15:49:35,633902307+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.0996732e+07
=== Step 11: 2024-12-16T15:49:36,647248179+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.2160201e+07
=== Step 12: 2024-12-16T15:49:37,663024249+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.3322686e+07
=== Step 13: 2024-12-16T15:49:38,682719257+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.447508e+07
=== Step 14: 2024-12-16T15:49:39,696938377+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.5622622e+07
=== Step 15: 2024-12-16T15:49:40,712562869+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="1018bef3-4b44-4f54-aa68-45fc159ee265",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.6519105e+07 batching-2=== Step 0: 2024-12-16T15:50:48,180828422+01:00
=== Step 1: 2024-12-16T15:50:49,202082470+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 766985
=== Step 2: 2024-12-16T15:50:50,218864887+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.712576e+06
=== Step 3: 2024-12-16T15:50:51,238460470+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 2.846777e+06
=== Step 4: 2024-12-16T15:50:52,253083715+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 4.052889e+06
=== Step 5: 2024-12-16T15:50:53,267904710+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 5.220396e+06
=== Step 6: 2024-12-16T15:50:54,283451381+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 6.378984e+06
=== Step 7: 2024-12-16T15:50:55,304076543+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 7.475826e+06
=== Step 8: 2024-12-16T15:50:56,318229950+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 8.644039e+06
=== Step 9: 2024-12-16T15:50:57,332883110+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 9.767176e+06
=== Step 10: 2024-12-16T15:50:58,345458786+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.0924412e+07
=== Step 11: 2024-12-16T15:50:59,359149580+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.2103512e+07
=== Step 12: 2024-12-16T15:51:00,373009015+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.3215526e+07
=== Step 13: 2024-12-16T15:51:01,383947577+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.4357692e+07
=== Step 14: 2024-12-16T15:51:02,397871874+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.5498857e+07
=== Step 15: 2024-12-16T15:51:03,419258504+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="8714502b-68f4-495d-ac04-43daaac29e69",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.6519105e+07 batching-3=== Step 0: 2024-12-16T15:52:21,557555315+01:00
=== Step 1: 2024-12-16T15:52:22,588161825+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 733360
=== Step 2: 2024-12-16T15:52:23,598105509+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.707804e+06
=== Step 3: 2024-12-16T15:52:24,609804063+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 2.809491e+06
=== Step 4: 2024-12-16T15:52:25,625337319+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 3.927862e+06
=== Step 5: 2024-12-16T15:52:26,636396041+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 5.110002e+06
=== Step 6: 2024-12-16T15:52:27,652329616+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 6.302457e+06
=== Step 7: 2024-12-16T15:52:28,662959666+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 7.43236e+06
=== Step 8: 2024-12-16T15:52:29,675925365+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 8.598355e+06
=== Step 9: 2024-12-16T15:52:30,689062153+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 9.797821e+06
=== Step 10: 2024-12-16T15:52:31,704479779+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.0911129e+07
=== Step 11: 2024-12-16T15:52:32,718040442+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.206504e+07
=== Step 12: 2024-12-16T15:52:33,728085856+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.3183748e+07
=== Step 13: 2024-12-16T15:52:34,740337198+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.4287112e+07
=== Step 14: 2024-12-16T15:52:35,754972220+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.5495808e+07
=== Step 15: 2024-12-16T15:52:36,772794534+01:00
otelcol_receiver_accepted_log_records{receiver="filelog",service_instance_id="f4546346-b6dd-4d45-a3a7-40ddf4698e75",service_name="otelcontribcol",service_version="0.114.0-dev",transport=""} 1.6519105e+07 |
Great question. I'd love to have a synthetic benchmark that can mirror "real-world" performance. For now, I've been relying on the manual labor of building the binary and running it on an actual file. |
I ran the fileconsumer benchmarks on main and this branch and it does appear that there are some substantial memory & allocation impacts from the changes.
This benchmark doesn't actually perform any work in the |
EDIT: The original benchstat results I posted in this comment were flawed, I have now updated them with correct results, which are not as bad. I tried to improve the allocations stats by pre-allocating memory for the batched entries in the following commits: Here are the stats comparing main and current state. I'll look into using a pool of buffers to further enhance performance. $ benchstat /tmp/main.txt /tmp/batch.txt
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
│ /tmp/main.txt │ /tmp/batch.txt │
│ sec/op │ sec/op vs base │
FileInput/Single-20 146.7µ ± 2% 152.0µ ± 55% +3.59% (p=0.004 n=10)
FileInput/Glob-20 161.2µ ± 3% 170.9µ ± 5% +6.01% (p=0.002 n=10)
FileInput/MultiGlob-20 163.4µ ± 5% 181.5µ ± 10% +11.09% (p=0.000 n=10)
FileInput/MaxConcurrent-20 589.5µ ± 7% 652.1µ ± 11% +10.61% (p=0.000 n=10)
FileInput/FngrPrntLarge-20 147.0µ ± 5% 155.4µ ± 5% +5.75% (p=0.005 n=10)
FileInput/FngrPrntSmall-20 146.6µ ± 1% 154.0µ ± 9% +5.06% (p=0.000 n=10)
FileInput/NoFlush-20 148.2µ ± 2% 152.3µ ± 6% +2.77% (p=0.029 n=10)
FileInput/Many-20 2.207m ± 11% 2.594m ± 62% +17.56% (p=0.000 n=10)
geomean 251.6µ 271.0µ +7.71%
│ /tmp/main.txt │ /tmp/batch.txt │
│ B/op │ B/op vs base │
FileInput/Single-20 15.00 ± 33% 100.50 ± 50% +570.00% (p=0.000 n=10)
FileInput/Glob-20 79.50 ± 64% 345.00 ± 238% +333.96% (p=0.000 n=10)
FileInput/MultiGlob-20 69.00 ± 101% 383.50 ± 67% +455.80% (p=0.000 n=10)
FileInput/MaxConcurrent-20 151.0 ± 160% 4758.0 ± 54% +3050.99% (p=0.000 n=10)
FileInput/FngrPrntLarge-20 43.50 ± 45% 167.50 ± 78% +285.06% (p=0.000 n=10)
FileInput/FngrPrntSmall-20 12.00 ± 100% 70.50 ± 191% +487.50% (p=0.000 n=10)
FileInput/NoFlush-20 13.00 ± 46% 133.50 ± 35% +926.92% (p=0.000 n=10)
FileInput/Many-20 28.93Ki ± 65% 370.52Ki ± 340% +1180.93% (p=0.000 n=10)
geomean 84.08 664.1 +689.88%
│ /tmp/main.txt │ /tmp/batch.txt │
│ allocs/op │ allocs/op vs base │
FileInput/Single-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
FileInput/Glob-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10)
FileInput/MultiGlob-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
FileInput/MaxConcurrent-20 0.000 ± 0% 3.000 ± 67% ? (p=0.000 n=10)
FileInput/FngrPrntLarge-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
FileInput/FngrPrntSmall-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
FileInput/NoFlush-20 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹
FileInput/Many-20 28.50 ± 58% 264.50 ± 336% +828.07% (p=0.000 n=10)
geomean ² ? ²
¹ all samples are equal
² summaries must be >0 to compute geomean |
I took a stab at implementing pooling of the buffers, as opposed to pre-allocating them. Comparing the benchmarks, it doesn't seem to give any performance gains though. Let me know if I missed something. benchstat /tmp/batch.txt /tmp/pool.txt
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
│ /tmp/batch.txt │ /tmp/pool.txt │
│ sec/op │ sec/op vs base │
FileInput/Single-20 84.73µ ± 1% 100.77µ ± 2% +18.92% (p=0.000 n=10)
FileInput/Glob-20 93.76µ ± 2% 125.43µ ± 3% +33.78% (p=0.000 n=10)
FileInput/MultiGlob-20 94.60µ ± 4% 126.93µ ± 2% +34.17% (p=0.000 n=10)
FileInput/MaxConcurrent-20 341.7µ ± 1% 406.9µ ± 3% +19.10% (p=0.000 n=10)
FileInput/FngrPrntLarge-20 85.16µ ± 1% 101.72µ ± 2% +19.45% (p=0.000 n=10)
FileInput/FngrPrntSmall-20 85.09µ ± 1% 101.94µ ± 1% +19.81% (p=0.000 n=10)
FileInput/NoFlush-20 84.26µ ± 1% 100.80µ ± 1% +19.63% (p=0.000 n=10)
FileInput/Many-20 1.297m ± 8% 1.585m ± 18% +22.24% (p=0.000 n=10)
geomean 145.7µ 179.6µ +23.24%
│ /tmp/batch.txt │ /tmp/pool.txt │
│ B/op │ B/op vs base │
FileInput/Single-20 73.50 ± 48% 10406.50 ± 1% +14058.50% (p=0.000 n=10)
FileInput/Glob-20 317.0 ± 47% 41682.0 ± 0% +13048.90% (p=0.000 n=10)
FileInput/MultiGlob-20 466.5 ± 66% 41686.0 ± 0% +8835.91% (p=0.000 n=10)
FileInput/MaxConcurrent-20 1.494Ki ± 60% 40.941Ki ± 1% +2640.10% (p=0.000 n=10)
FileInput/FngrPrntLarge-20 86.50 ± 108% 10393.50 ± 1% +11915.61% (p=0.000 n=10)
FileInput/FngrPrntSmall-20 72.00 ± 47% 10359.50 ± 0% +14288.19% (p=0.000 n=10)
FileInput/NoFlush-20 72.00 ± 47% 10366.00 ± 0% +14297.22% (p=0.000 n=10)
FileInput/Many-20 143.7Ki ± 136% 1046.1Ki ± 8% +627.93% (p=0.000 n=10)
geomean 426.6 30.50Ki +7221.78%
│ /tmp/batch.txt │ /tmp/pool.txt │
│ allocs/op │ allocs/op vs base │
FileInput/Single-20 0.000 ± 0% 5.000 ± 0% ? (p=0.000 n=10)
FileInput/Glob-20 0.00 ± 0% 20.00 ± 5% ? (p=0.000 n=10)
FileInput/MultiGlob-20 0.00 ± 0% 20.00 ± 5% ? (p=0.000 n=10)
FileInput/MaxConcurrent-20 500.0m ± ? 21000.0m ± 5% +4100.00% (p=0.000 n=10)
FileInput/FngrPrntLarge-20 0.000 ± 0% 5.000 ± 0% ? (p=0.000 n=10)
FileInput/FngrPrntSmall-20 0.000 ± 0% 5.000 ± 0% ? (p=0.000 n=10)
FileInput/NoFlush-20 0.000 ± 0% 5.000 ± 0% ? (p=0.000 n=10)
FileInput/Many-20 103.0 ± 133% 574.5 ± 61% +457.77% (p=0.000 n=10)
geomean ¹ 15.31 ?
¹ summaries must be >0 to compute geomean |
One thing I notice is that we're now making a copy of the attributes map for every token. This might not be necessary. Generally, the attributes describe the file, so should be the same for every token emitted by a given reader. However, What if instead of Some nuances to this:
This might be a lot of work to test but if it makes sense to you it might be worth it. Otherwise, I'm not seeing a lot of room for optimization. I know you've put a lot into this but if we really think this change introduces memory usage by orders of magnitude, then I think we may need to look at other designs such as using callbacks to update offsets. |
This is true, some of the attributes are the same for all tokens and (currently) only the record number attribute changes for each token. A similar suggestion was offered from @swiatekm, in a different fashion: have one (a single instance of) attribute map for the common attributes (those describing the source file) and a second attribute map that would be allocated for every record - it would currently only hold the record number attribute. The solution with a single int for the record number surely uses less memory, but the approach with separate attribute maps is probably easier to potentially extend if a new attribute needs to be added in the future? |
I have removed memory allocations for attributes in branch prevent-allocations-for-attributes by following the approach described by Dan. Here's the diff with current branch. Here's the benchmark comparison between the two branches:
The allocation counts are down, as visible in the |
Removes the need to allocate memory for each token's attributes. The file-related attributes that are common to all tokens only exist in a single instance now in Reader. The row number attributes are only created later, when Entry is created from a token.
After incorporating the benchmark added in #38054, I can now compare main$ (cd pkg/stanza/operator/input/file/ && go test -benchmem -run=^$ -bench Benchmark . -v -count=6 | tee /tmp/fileinput-main-$(git rev-parse --short HEAD).txt)
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
BenchmarkReadExistingLogs
BenchmarkReadExistingLogs/0-lines
BenchmarkReadExistingLogs/0-lines-20 70484 23031 ns/op 26841 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 47827 22781 ns/op 26872 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 46557 24626 ns/op 26976 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 49556 20808 ns/op 26881 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 48490 21711 ns/op 26926 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 54570 23494 ns/op 26957 B/op 46 allocs/op
BenchmarkReadExistingLogs/1-lines
BenchmarkReadExistingLogs/1-lines-20 4201 281598 ns/op 99820 B/op 192 allocs/op
BenchmarkReadExistingLogs/1-lines-20 3597 278643 ns/op 101172 B/op 195 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4202 274729 ns/op 100037 B/op 193 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4074 275832 ns/op 102114 B/op 197 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4161 276897 ns/op 101796 B/op 196 allocs/op
BenchmarkReadExistingLogs/1-lines-20 5718 286110 ns/op 102193 B/op 197 allocs/op
BenchmarkReadExistingLogs/2-lines
BenchmarkReadExistingLogs/2-lines-20 3891 286790 ns/op 101980 B/op 200 allocs/op
BenchmarkReadExistingLogs/2-lines-20 6790 299994 ns/op 103685 B/op 204 allocs/op
BenchmarkReadExistingLogs/2-lines-20 4230 280316 ns/op 103476 B/op 203 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3735 281811 ns/op 101645 B/op 200 allocs/op
BenchmarkReadExistingLogs/2-lines-20 4182 295597 ns/op 102921 B/op 202 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3922 305502 ns/op 103116 B/op 203 allocs/op
BenchmarkReadExistingLogs/10-lines
BenchmarkReadExistingLogs/10-lines-20 3388 340723 ns/op 115932 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 5371 330354 ns/op 114449 B/op 256 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3734 327431 ns/op 115598 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 4615 332575 ns/op 115508 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3736 318994 ns/op 116489 B/op 259 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3508 317881 ns/op 115664 B/op 258 allocs/op
BenchmarkReadExistingLogs/20-lines
BenchmarkReadExistingLogs/20-lines-20 3043 370798 ns/op 132970 B/op 330 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3166 399654 ns/op 132085 B/op 328 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3770 361589 ns/op 131562 B/op 328 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3362 344698 ns/op 133441 B/op 331 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3822 358177 ns/op 132667 B/op 330 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3208 365742 ns/op 132315 B/op 329 allocs/op
BenchmarkReadExistingLogs/100-lines
BenchmarkReadExistingLogs/100-lines-20 1645 691607 ns/op 265208 B/op 896 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1035 1078240 ns/op 271741 B/op 909 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1249 935385 ns/op 279790 B/op 924 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1726 911764 ns/op 276851 B/op 918 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1402 914500 ns/op 278960 B/op 922 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1326 925553 ns/op 281257 B/op 927 allocs/op
BenchmarkReadExistingLogs/1000-lines
BenchmarkReadExistingLogs/1000-lines-20 276 4381826 ns/op 1741158 B/op 7247 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 302 4746414 ns/op 1746959 B/op 7258 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 333 4715565 ns/op 1748366 B/op 7261 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 309 4407227 ns/op 1743468 B/op 7252 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 283 4436628 ns/op 1747759 B/op 7260 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 322 4404681 ns/op 1745806 B/op 7256 allocs/op
PASS
ok github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file 70.270s batch$ (cd pkg/stanza/operator/input/file/ && go test -benchmem -run=^$ -bench Benchmark . -v -count=6 | tee /tmp/fileinput-batch-$(git rev-parse --short HEAD).txt)
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
BenchmarkReadExistingLogs
BenchmarkReadExistingLogs/0-lines
BenchmarkReadExistingLogs/0-lines-20 60921 18329 ns/op 26757 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 71128 19956 ns/op 26823 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 58737 20652 ns/op 26839 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 53828 19314 ns/op 26818 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 54476 20152 ns/op 26840 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 55768 19443 ns/op 26803 B/op 45 allocs/op
BenchmarkReadExistingLogs/1-lines
BenchmarkReadExistingLogs/1-lines-20 3412 395931 ns/op 176782 B/op 602 allocs/op
BenchmarkReadExistingLogs/1-lines-20 2818 391429 ns/op 178631 B/op 609 allocs/op
BenchmarkReadExistingLogs/1-lines-20 3433 350361 ns/op 180602 B/op 616 allocs/op
BenchmarkReadExistingLogs/1-lines-20 3492 363100 ns/op 180283 B/op 615 allocs/op
BenchmarkReadExistingLogs/1-lines-20 2982 360208 ns/op 182287 B/op 622 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4012 389339 ns/op 177750 B/op 606 allocs/op
BenchmarkReadExistingLogs/2-lines
BenchmarkReadExistingLogs/2-lines-20 2760 370782 ns/op 182384 B/op 624 allocs/op
BenchmarkReadExistingLogs/2-lines-20 2751 373535 ns/op 180724 B/op 617 allocs/op
BenchmarkReadExistingLogs/2-lines-20 2713 409702 ns/op 183695 B/op 629 allocs/op
BenchmarkReadExistingLogs/2-lines-20 2908 353704 ns/op 182225 B/op 623 allocs/op
BenchmarkReadExistingLogs/2-lines-20 2598 402355 ns/op 185016 B/op 634 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3564 355158 ns/op 183739 B/op 628 allocs/op
BenchmarkReadExistingLogs/10-lines
BenchmarkReadExistingLogs/10-lines-20 2720 398449 ns/op 197345 B/op 687 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3638 403747 ns/op 198275 B/op 690 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3129 412386 ns/op 195996 B/op 682 allocs/op
BenchmarkReadExistingLogs/10-lines-20 2606 437088 ns/op 194788 B/op 678 allocs/op
BenchmarkReadExistingLogs/10-lines-20 2876 403799 ns/op 197543 B/op 688 allocs/op
BenchmarkReadExistingLogs/10-lines-20 2418 430050 ns/op 194630 B/op 677 allocs/op
BenchmarkReadExistingLogs/20-lines
BenchmarkReadExistingLogs/20-lines-20 2566 455933 ns/op 214970 B/op 762 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3277 448540 ns/op 218362 B/op 775 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3136 442772 ns/op 214775 B/op 762 allocs/op
BenchmarkReadExistingLogs/20-lines-20 2856 459318 ns/op 211965 B/op 751 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3038 358299 ns/op 211544 B/op 749 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3648 474670 ns/op 213288 B/op 756 allocs/op
BenchmarkReadExistingLogs/100-lines
BenchmarkReadExistingLogs/100-lines-20 1639 829174 ns/op 355692 B/op 1363 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1296 787417 ns/op 366267 B/op 1402 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1647 767658 ns/op 357199 B/op 1368 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1429 773337 ns/op 360601 B/op 1381 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1454 748198 ns/op 358960 B/op 1375 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1904 795617 ns/op 359363 B/op 1377 allocs/op
BenchmarkReadExistingLogs/1000-lines
BenchmarkReadExistingLogs/1000-lines-20 301 3755205 ns/op 1831472 B/op 7739 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 393 3470412 ns/op 1850409 B/op 7809 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 348 3560141 ns/op 1841913 B/op 7776 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 406 3821434 ns/op 1858603 B/op 7838 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 386 3808140 ns/op 1846718 B/op 7795 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 381 3715700 ns/op 1849136 B/op 7804 allocs/op
PASS
ok github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file 59.819s $ benchstat /tmp/fileinput-main-187259e7d7.txt /tmp/fileinput-batch-006ae63233.txt
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-batch-006ae63233.txt │
│ sec/op │ sec/op vs base │
ReadExistingLogs/0-lines-20 22.91µ ± 9% 19.70µ ± 7% -14.00% (p=0.002 n=6)
ReadExistingLogs/1-lines-20 277.8µ ± 3% 376.2µ ± 7% +35.44% (p=0.002 n=6)
ReadExistingLogs/2-lines-20 291.2µ ± 5% 372.2µ ± 10% +27.80% (p=0.002 n=6)
ReadExistingLogs/10-lines-20 328.9µ ± 4% 408.1µ ± 7% +24.08% (p=0.002 n=6)
ReadExistingLogs/20-lines-20 363.7µ ± 10% 452.2µ ± 21% +24.36% (p=0.026 n=6)
ReadExistingLogs/100-lines-20 920.0µ ± 25% 780.4µ ± 6% ~ (p=0.065 n=6)
ReadExistingLogs/1000-lines-20 4.422m ± 7% 3.735m ± 7% -15.52% (p=0.002 n=6)
geomean 367.3µ 394.4µ +7.38%
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-batch-006ae63233.txt │
│ B/op │ B/op vs base │
ReadExistingLogs/0-lines-20 26.27Ki ± 0% 26.19Ki ± 0% -0.31% (p=0.002 n=6)
ReadExistingLogs/1-lines-20 99.11Ki ± 2% 175.25Ki ± 2% +76.83% (p=0.002 n=6)
ReadExistingLogs/2-lines-20 100.6Ki ± 1% 178.7Ki ± 1% +77.68% (p=0.002 n=6)
ReadExistingLogs/10-lines-20 112.9Ki ± 1% 192.1Ki ± 1% +70.08% (p=0.002 n=6)
ReadExistingLogs/20-lines-20 129.4Ki ± 1% 209.0Ki ± 2% +61.54% (p=0.002 n=6)
ReadExistingLogs/100-lines-20 271.4Ki ± 5% 350.7Ki ± 2% +29.24% (p=0.002 n=6)
ReadExistingLogs/1000-lines-20 1.665Mi ± 0% 1.762Mi ± 1% +5.81% (p=0.002 n=6)
geomean 150.8Ki 214.4Ki +42.22%
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-batch-006ae63233.txt │
│ allocs/op │ allocs/op vs base │
ReadExistingLogs/0-lines-20 46.00 ± 2% 45.00 ± 0% ~ (p=0.061 n=6)
ReadExistingLogs/1-lines-20 195.5 ± 2% 612.0 ± 2% +213.04% (p=0.002 n=6)
ReadExistingLogs/2-lines-20 202.5 ± 1% 626.0 ± 1% +209.14% (p=0.002 n=6)
ReadExistingLogs/10-lines-20 258.0 ± 1% 684.5 ± 1% +165.31% (p=0.002 n=6)
ReadExistingLogs/20-lines-20 329.5 ± 0% 759.0 ± 2% +130.35% (p=0.002 n=6)
ReadExistingLogs/100-lines-20 920.0 ± 3% 1376.0 ± 2% +49.57% (p=0.002 n=6)
ReadExistingLogs/1000-lines-20 7.257k ± 0% 7.800k ± 1% +7.48% (p=0.002 n=6)
geomean 374.5 715.6 +91.08% This result still shows a performance penalty. Next, I want to check how changes in prevent-allocations-for-attributes affect it. |
Here's the comparison between main$ (cd pkg/stanza/operator/input/file/ && go test -benchmem -run=^$ -bench Benchmark . -v -count=6 | tee /tmp/fileinput-main-$(git rev-parse --short HEAD).txt)
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
BenchmarkReadExistingLogs
BenchmarkReadExistingLogs/0-lines
BenchmarkReadExistingLogs/0-lines-20 70484 23031 ns/op 26841 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 47827 22781 ns/op 26872 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 46557 24626 ns/op 26976 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 49556 20808 ns/op 26881 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 48490 21711 ns/op 26926 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 54570 23494 ns/op 26957 B/op 46 allocs/op
BenchmarkReadExistingLogs/1-lines
BenchmarkReadExistingLogs/1-lines-20 4201 281598 ns/op 99820 B/op 192 allocs/op
BenchmarkReadExistingLogs/1-lines-20 3597 278643 ns/op 101172 B/op 195 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4202 274729 ns/op 100037 B/op 193 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4074 275832 ns/op 102114 B/op 197 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4161 276897 ns/op 101796 B/op 196 allocs/op
BenchmarkReadExistingLogs/1-lines-20 5718 286110 ns/op 102193 B/op 197 allocs/op
BenchmarkReadExistingLogs/2-lines
BenchmarkReadExistingLogs/2-lines-20 3891 286790 ns/op 101980 B/op 200 allocs/op
BenchmarkReadExistingLogs/2-lines-20 6790 299994 ns/op 103685 B/op 204 allocs/op
BenchmarkReadExistingLogs/2-lines-20 4230 280316 ns/op 103476 B/op 203 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3735 281811 ns/op 101645 B/op 200 allocs/op
BenchmarkReadExistingLogs/2-lines-20 4182 295597 ns/op 102921 B/op 202 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3922 305502 ns/op 103116 B/op 203 allocs/op
BenchmarkReadExistingLogs/10-lines
BenchmarkReadExistingLogs/10-lines-20 3388 340723 ns/op 115932 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 5371 330354 ns/op 114449 B/op 256 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3734 327431 ns/op 115598 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 4615 332575 ns/op 115508 B/op 258 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3736 318994 ns/op 116489 B/op 259 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3508 317881 ns/op 115664 B/op 258 allocs/op
BenchmarkReadExistingLogs/20-lines
BenchmarkReadExistingLogs/20-lines-20 3043 370798 ns/op 132970 B/op 330 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3166 399654 ns/op 132085 B/op 328 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3770 361589 ns/op 131562 B/op 328 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3362 344698 ns/op 133441 B/op 331 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3822 358177 ns/op 132667 B/op 330 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3208 365742 ns/op 132315 B/op 329 allocs/op
BenchmarkReadExistingLogs/100-lines
BenchmarkReadExistingLogs/100-lines-20 1645 691607 ns/op 265208 B/op 896 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1035 1078240 ns/op 271741 B/op 909 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1249 935385 ns/op 279790 B/op 924 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1726 911764 ns/op 276851 B/op 918 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1402 914500 ns/op 278960 B/op 922 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1326 925553 ns/op 281257 B/op 927 allocs/op
BenchmarkReadExistingLogs/1000-lines
BenchmarkReadExistingLogs/1000-lines-20 276 4381826 ns/op 1741158 B/op 7247 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 302 4746414 ns/op 1746959 B/op 7258 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 333 4715565 ns/op 1748366 B/op 7261 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 309 4407227 ns/op 1743468 B/op 7252 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 283 4436628 ns/op 1747759 B/op 7260 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 322 4404681 ns/op 1745806 B/op 7256 allocs/op
PASS
ok github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file 70.270s prevent-allocations-for-attributes$ (cd pkg/stanza/operator/input/file/ && go test -benchmem -run=^$ -bench Benchmark . -v -count=6 | tee /tmp/fileinput-noattr-$(git rev-parse --short HEAD).txt)
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
BenchmarkReadExistingLogs
BenchmarkReadExistingLogs/0-lines
BenchmarkReadExistingLogs/0-lines-20 65566 22851 ns/op 26846 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 51938 22194 ns/op 26851 B/op 45 allocs/op
BenchmarkReadExistingLogs/0-lines-20 43855 23682 ns/op 26927 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 52132 23865 ns/op 26926 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 52185 24350 ns/op 26928 B/op 46 allocs/op
BenchmarkReadExistingLogs/0-lines-20 53761 22944 ns/op 26952 B/op 46 allocs/op
BenchmarkReadExistingLogs/1-lines
BenchmarkReadExistingLogs/1-lines-20 4078 288720 ns/op 106755 B/op 198 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4292 289172 ns/op 107036 B/op 198 allocs/op
BenchmarkReadExistingLogs/1-lines-20 4126 289504 ns/op 106870 B/op 198 allocs/op
BenchmarkReadExistingLogs/1-lines-20 5118 291535 ns/op 107268 B/op 199 allocs/op
BenchmarkReadExistingLogs/1-lines-20 3829 269770 ns/op 107881 B/op 200 allocs/op
BenchmarkReadExistingLogs/1-lines-20 6006 234947 ns/op 105643 B/op 196 allocs/op
BenchmarkReadExistingLogs/2-lines
BenchmarkReadExistingLogs/2-lines-20 5472 310275 ns/op 107026 B/op 203 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3956 302870 ns/op 108422 B/op 205 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3848 299569 ns/op 109148 B/op 206 allocs/op
BenchmarkReadExistingLogs/2-lines-20 4045 288719 ns/op 108325 B/op 205 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3379 304325 ns/op 108676 B/op 206 allocs/op
BenchmarkReadExistingLogs/2-lines-20 3439 316499 ns/op 108564 B/op 205 allocs/op
BenchmarkReadExistingLogs/10-lines
BenchmarkReadExistingLogs/10-lines-20 3501 339380 ns/op 120970 B/op 260 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3459 335376 ns/op 122676 B/op 263 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3519 336288 ns/op 122348 B/op 263 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3559 333274 ns/op 121029 B/op 260 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3469 328585 ns/op 122990 B/op 264 allocs/op
BenchmarkReadExistingLogs/10-lines-20 3159 336813 ns/op 121245 B/op 261 allocs/op
BenchmarkReadExistingLogs/20-lines
BenchmarkReadExistingLogs/20-lines-20 3208 381970 ns/op 140645 B/op 336 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3084 378508 ns/op 139418 B/op 334 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3061 388351 ns/op 139785 B/op 335 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3114 371635 ns/op 138348 B/op 332 allocs/op
BenchmarkReadExistingLogs/20-lines-20 2811 380827 ns/op 138303 B/op 332 allocs/op
BenchmarkReadExistingLogs/20-lines-20 3537 356651 ns/op 139123 B/op 334 allocs/op
BenchmarkReadExistingLogs/100-lines
BenchmarkReadExistingLogs/100-lines-20 1651 687588 ns/op 282687 B/op 919 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1670 695154 ns/op 288499 B/op 929 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1923 668218 ns/op 286785 B/op 926 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1627 707902 ns/op 288726 B/op 929 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1495 700683 ns/op 291439 B/op 934 allocs/op
BenchmarkReadExistingLogs/100-lines-20 1671 717894 ns/op 291303 B/op 934 allocs/op
BenchmarkReadExistingLogs/1000-lines
BenchmarkReadExistingLogs/1000-lines-20 351 3649849 ns/op 1756591 B/op 7257 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 421 3562851 ns/op 1759938 B/op 7263 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 370 3502160 ns/op 1766711 B/op 7275 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 379 3516728 ns/op 1766709 B/op 7276 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 368 3337492 ns/op 1770093 B/op 7281 allocs/op
BenchmarkReadExistingLogs/1000-lines-20 354 3179941 ns/op 1770700 B/op 7282 allocs/op
PASS
ok github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file 76.871s $ benchstat /tmp/fileinput-main-187259e7d7.txt /tmp/fileinput-noattr-dfab829acd.txt
goos: linux
goarch: amd64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/file
cpu: 13th Gen Intel(R) Core(TM) i7-13700H
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-noattr-dfab829acd.txt │
│ sec/op │ sec/op vs base │
ReadExistingLogs/0-lines-20 22.91µ ± 9% 23.31µ ± 5% ~ (p=0.485 n=6)
ReadExistingLogs/1-lines-20 277.8µ ± 3% 288.9µ ± 19% ~ (p=0.394 n=6)
ReadExistingLogs/2-lines-20 291.2µ ± 5% 303.6µ ± 5% ~ (p=0.093 n=6)
ReadExistingLogs/10-lines-20 328.9µ ± 4% 335.8µ ± 2% ~ (p=0.132 n=6)
ReadExistingLogs/20-lines-20 363.7µ ± 10% 379.7µ ± 6% ~ (p=0.240 n=6)
ReadExistingLogs/100-lines-20 920.0µ ± 25% 697.9µ ± 4% -24.14% (p=0.026 n=6)
ReadExistingLogs/1000-lines-20 4.422m ± 7% 3.509m ± 9% -20.64% (p=0.002 n=6)
geomean 367.3µ 349.6µ -4.81%
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-noattr-dfab829acd.txt │
│ B/op │ B/op vs base │
ReadExistingLogs/0-lines-20 26.27Ki ± 0% 26.30Ki ± 0% ~ (p=0.965 n=6)
ReadExistingLogs/1-lines-20 99.11Ki ± 2% 104.45Ki ± 1% +5.39% (p=0.002 n=6)
ReadExistingLogs/2-lines-20 100.6Ki ± 1% 106.0Ki ± 1% +5.31% (p=0.002 n=6)
ReadExistingLogs/10-lines-20 112.9Ki ± 1% 118.9Ki ± 1% +5.33% (p=0.002 n=6)
ReadExistingLogs/20-lines-20 129.4Ki ± 1% 136.0Ki ± 1% +5.12% (p=0.002 n=6)
ReadExistingLogs/100-lines-20 271.4Ki ± 5% 281.8Ki ± 2% +3.85% (p=0.002 n=6)
ReadExistingLogs/1000-lines-20 1.665Mi ± 0% 1.685Mi ± 1% +1.16% (p=0.002 n=6)
geomean 150.8Ki 156.4Ki +3.73%
│ /tmp/fileinput-main-187259e7d7.txt │ /tmp/fileinput-noattr-dfab829acd.txt │
│ allocs/op │ allocs/op vs base │
ReadExistingLogs/0-lines-20 46.00 ± 2% 46.00 ± 2% ~ (p=1.000 n=6)
ReadExistingLogs/1-lines-20 195.5 ± 2% 198.0 ± 1% +1.28% (p=0.009 n=6)
ReadExistingLogs/2-lines-20 202.5 ± 1% 205.0 ± 1% +1.23% (p=0.009 n=6)
ReadExistingLogs/10-lines-20 258.0 ± 1% 262.0 ± 1% +1.55% (p=0.002 n=6)
ReadExistingLogs/20-lines-20 329.5 ± 0% 334.0 ± 1% +1.37% (p=0.002 n=6)
ReadExistingLogs/100-lines-20 920.0 ± 3% 929.0 ± 1% +0.98% (p=0.024 n=6)
ReadExistingLogs/1000-lines-20 7.257k ± 0% 7.276k ± 0% +0.25% (p=0.015 n=6)
geomean 374.5 378.1 +0.95% @djaglowski looks like your suggestion for attributes has actually worked. I'm going to add this commit andrzej-stencel@1095dee to this branch. Please let me know your thoughts on this. |
I modified the test cases to scale up to 100,000 lines per file and increased run count to 20 and see similar results. I think we should pull in the change.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good to me. The one thing I'd call out is that we've removed tests for the attributes. It would be good to add equivalent ones somewhere so we know we're not regressing on the actual behavior.
Description
Modifies the File consumer to emit logs in batches as opposed to sending each log individually through the Stanza pipeline and on to the Log Emitter.
Here are the changes introduced:
Reader::ReadToEnd
method in File consumer to collect the tokens scanned from the file into batches. At this point, the Reader still emits each token individually, as theemit.Callback
function only accepts a single token.emit.Callback
function signature to accept a slice of tokens as opposed to a single token, and changed the Reader to emit a batch of tokens in one request. At this point, the batches are still split into individual tokens inside theemit
function, because the Stanza operators can only process one entry at a time.ProcessBatch
method to Stanza operators and used it in theemit
function. At this point, the batch of tokens is translated to a batch of entries and passed to Log Emitter as a whole batch. The batch is still split in the Log Emitter, which callsconsumeFunc
for each entry in a loop.Slice of entries
[]entry.Entry
vs. slice of pointers[]*entry.Entry
I considered whether the
ProcessBatch
method in theOperator
interface should accept a slice of structs[]entry.Entry
or a slice of pointers[]*entry.Entry
. I ran some tests (similar to #35454) and they showed a 7-10% performance loss when using a slice of structs vs. a slice of pointers. That's why I decided to use the slice of pointers[]*entry.Entry
.Link to tracking issue
Testing
No changes in tests. The goal is for the functionality to not change and for performance to not decrease.
I have added a new benchmark in a separate PR #38054 that should be helpful in assessing the performance impact of this change.
Documentation
These are internal changes, no user documentation needs changing.