Skip to content

Implement perf optimization using MaybeUninit#230

Draft
tcharding wants to merge 1 commit intorust-bitcoin:masterfrom
tcharding:push-qzvyppnponrl
Draft

Implement perf optimization using MaybeUninit#230
tcharding wants to merge 1 commit intorust-bitcoin:masterfrom
tcharding:push-qzvyppnponrl

Conversation

@tcharding
Copy link
Copy Markdown
Member

Using a zero initialized array on the stack may be slower than using a MaybeUninit because of the required initialization to zero just to overwrite the buffer.

However using (testing) MaybeUninit is a bit of a nuisance so leave the original function drain_to_slice in the codebase but cfg it out unless we are testing.

Note to review: This is a bit smelly, feel free to reprimand me.

Close #146

@tcharding
Copy link
Copy Markdown
Member Author

tcharding commented Apr 13, 2026

I wrote the code with an Opus 4.6 (all the smelly bits, duplicate test function etc was all me).

Using a zero initialized array on the stack may be slower than using a
`MaybeUninit` because of the required initialization to zero just to
overwrite the buffer.

However using (testing) `MaybeUninit` is a bit of a nuisance so leave
the original function `drain_to_slice` in the codebase but cfg it out
unless we are testing.
Comment thread src/lib.rs
// SAFETY: `[MaybeUninit<u8>; N]` has no initialization requirement,
// so an uninitialized array of them is sound. This is the standard
// `uninit_array` pattern.
let mut ret: [MaybeUninit<u8>; N] = unsafe { MaybeUninit::uninit().assume_init() };
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.

In 1705412:

Can you find a citation for this being the "standard uninit_array pattern"? It appears intuitively that MaybeUninit::uninit().assume_init() is always unsound.

AFAICT, by reading for example this rust-lang thread, the correct way to do this on stable Rust is [const { MaybeUninit::uninit() }; N].

Comment thread src/iter.rs
unsafe {
core::ptr::write(ptr, byte?);
ptr = ptr.add(1);
}
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.

In 1705412:

Why use ptr::write instead of Maybeuninit::write? That would save you unsafety, casts, and pointer arithmetic.

@apoelstra
Copy link
Copy Markdown
Member

I wrote the code with an Opus 4.6

Thanks for the disclosure. From a new contributor this would be a "close without bothering to comment" PR.

@tcharding
Copy link
Copy Markdown
Member Author

Ouch, I guess I should not to vibe code issues that I don't care about. Sorry for using your time bro.

@tcharding tcharding marked this pull request as draft April 14, 2026 01:28
@tcharding
Copy link
Copy Markdown
Member Author

tcharding commented Apr 14, 2026

Drafting because for me personally this is not high priority.

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.

Use MaybeUninit in place of 0-initialized u8 arrays

2 participants