C
Chad Austin
chadaustin.me · Personal blog · on HN since 2009
Chad Austin writes about systems programming, Rust, performance, terminals, and hardware tinkering, drawing on experience at Dropbox.
What HN saysCommenters link his posts on performance, bitfields, CRTs and pixels, and unsafe Rust, and call his performance writing insightful.
53HN people shared it
24linked it in comments
43stories submitted
2.2Kstory points
4 months agolast shared
2009people per year2026
Most-shared posts
- 1Unsafe Rust is harder than C9 people · 120 points · first shared 2024 · 125 comments on HN
- 2Sum Types Are Coming (2015)6 people · 119 points · first shared 2015 · 113 comments on HN
- 3Dropbox Hack Week: GraphQL Server in Haskell4 people · 16 points · first shared 2016 · discussion on HN
- 4Terminal Latency on Windows (2024)3 people · 113 points · first shared 2024 · 93 comments on HN
- 5Two Years Working at Dropbox3 people · 108 points · first shared 2019 · 76 comments on HN
- 6Microsoft Sculpt Wired Conversion Mod3 people · 88 points · first shared 2021 · 70 comments on HN
- 7The Long-Term Problem with Dynamically Typed Languages3 people · 57 points · first shared 2015 · 93 comments on HN
- 8I just wanted Emacs to look nice – Using 24-bit color in terminals2 people · 527 points · first shared 2024 · 179 comments on HN
- 9Writing a Fast JSON Parser2 people · 381 points · first shared 2017 · 50 comments on HN
- 10The Story of Haskell at IMVU2 people · 227 points · first shared 2016 · 165 comments on HN
- 11Your Version Control and Build Systems Don't Scale2 people · 94 points · first shared 2010 · 53 comments on HN
- 12Mozilla’s Rejection of NativeClient Hurts the Open Web2 people · 85 points · first shared 2011 · 101 comments on HN
- 13Native Client is Widely Misunderstood (2011)2 people · 19 points · first shared 2011 · 22 comments on HN
- 14Emscripten bechmarks2 people · 3 points · first shared 2013 · discussion on HN
- 15The s/ directory is a home only for project commands2 people · 2 points · first shared 2017 · 1 comments on HN
What HN people wrote when they linked it
murderfs · 2021-02-24
> Given tantalum is a rare earth metal, it might be nice to replace it with a ceramic and maybe a 4 Ω resistor in series. I’d love any input here.
USB allows for 10uF of capacitance, and you don't seem to have an LDO on your board, so you don't need a minimum amount of ESR to maintain stability. I don't think there's any reason you can't just replace the tantalum with a ceramic?
> https://chadaustin.me/images/sculpt/pcbway-top.jpeg
This is shockingly bad. I was thinking of using PCBWay to assemble a run of a dozen or so PCBs, because JLCPCB is limited on solder mask color and part selection, but this has pretty firmly turned me away from that.
chadaustin · 2016-03-28
I love this topic and compiled a slew of related links last year: https://chadaustin.me/2015/11/crts-pixels-and-video-games/
mwcampbell · 2015-04-29
Another insightful post from Chad on performance is this one:
http://chadaustin.me/2009/02/logic-vs-array-processing/
When I read this post, I suddenly realized why one's chosen programming language (or more precisely, the compilation approach and runtime environment) has such an impact on application startup time, though he only briefly touched on that. Think of the logic required to locate and load each module or class as it's first needed (e.g. Python or a typical Java or .NET runtime) versus just mapping the executable into memory and jumping to main (AOT-compiled native code, best if statically linked). Good luck if your application uses the former approach and it typically starts when a user's computer starts up, on a computer with a spinning disk.
nextaccountic · 2021-12-19
Bitfields are hard! They are potentially unaligned, thus interact poorly with some language features, like pointers and references. And their size isn't a multiple of bytes, unlike any other value, which causes problems as well. They interact poorly with padding and the general idea of Rust ABIs that enables optimizations like reordering fields and using "niches" (invalid values) to find a more compact layout for structs and enums.
I agree Rust should eventually have some native support for bitfields, but only if it's a high quality spec that addresses the outstanding concerns - Rust should specifically avoid the C mess, which isn't usable for most projects.
But this doesn't mean bitfields can't be done in Rust; it's just not in the stdlib (yet). See this post[0] which contains a survey of various libraries (and their respective limitations), and this slightly older article [1]. Those articles somehow missed the modular-bitfield crate [2], which is perhaps the nicest to use, and is what I would recommend you.
If you don't care about the specifics you can get any crate discussed in the above articles and use them.
About interoperability with C (and C++), I really like bindgen, cbindgen and cxx. The bindgen book [3] is straighforward. This section of cxx documentation [4] also describes the tradeoffs between the different FFI approaches. I don't know Ada though, so I must ask: what does Ada do?
About this,
> I just don't see what Rust has to offer that Ada didn't already…
IshKebab · 2026-07-14
That's not quite true. I had a look into the Bun port and it's not like c2rust where it literally will convert every pointer access into `unsafe` and 50% of your code will be `unsafe`. It's a lot safer than that. They claim only 4% of lines are unsafe, and 78% of those are from C/C++ interop. That's more than a typical Rust project but it's still a lot less than C/C++ or Zig.
> I could rewrite anything in unsafe Rust like right now, despite being a novice in the language.
I really doubt that. Unsafe Rust is actually significantly more difficult to get right than C or C++. See e.g. https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/ or https://lucumr.pocoo.org/2022/1/30/unsafe-rust/
It's not too big of a deal because in idiomatic Rust you pretty much never write unsafe code (except for FFI), but it would be nice if it was not quite so hard (or poorly defined).
wordisside · 2026-01-08
But unsafe Rust, which is generally more often used in low-level code, is more difficult than C and C++.
https://rust-unofficial.github.io/too-many-lists/
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
disappoint · 2025-12-05
Please explain the differences in typical aliasing rules between C and Rust. And please explain posts like
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
https://news.ycombinator.com/item?id=41947921
https://lucumr.pocoo.org/2022/1/30/unsafe-rust/
lenkite · 2025-03-17
> With unsafe you get exactly the same kind of semantics as C
People seem to disagree.
Unsafe Rust Is Harder Than C
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
https://news.ycombinator.com/item?id=41944121
minetest2048 · 2024-10-31
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
HN discussion: https://news.ycombinator.com/item?id=41944121
While we at it, someone argued that Zig is nicer than unsafe Rust: https://zackoverflow.dev/writing/unsafe-rust-vs-zig/
pjmlp · 2024-09-20
Not at all, had Mozilla adopted PNaCL instead of coming up with asm.js, and WebAssembly would never come up, delaying everything for a decade.
Here is a memory refresher from 2011,
"Mozilla's Rejection of NativeClient Hurts the Open Web"
https://chadaustin.me/2011/01/mozillas-rejection-of-nativeclient-hurts…
wongogue · 2024-08-13
I don’t know if it’s my setup or just Windows quirks but even Alacritty feels slower than Windows Terminal.
You can also use Is It Snappy? from the App Store to test typing latency. It was made by Chad Austin who had problems similar to us.
https://chadaustin.me/2017/04/announcing-is-it-snappy/
eviks · 2024-05-22
here is some latency tests using an external camera, though that's Windows only, there might've been a similar one for Linux, but not sure
https://chadaustin.me/2024/02/windows-terminal-latency/
The other one where xterm is uber low is https://lwn.net/Articles/751763/ is using this tool with software-based screen capture https://pavelfatin.com/typometer/, not sure how reliable that is as a proxy for end-to-end (at the time of the benchmark Wayland wasn't supported)
NelsonMinar · 2024-04-08
Here's recent testing of Windows terminal latencies. It's 66ms in Microsoft's fancy new terminal. https://chadaustin.me/2024/02/windows-terminal-latency/
UnserMannInK · 2024-01-14
I have also used the K860 and I like it. I stumbled across Chad Austin’s Microsoft Sculpt wired conversion [1] and I have been using it for some time now. Apart from the abysmal function keys it’s a decent keyboard, and with QMK you can make it do whatever you want.
[1]: https://chadaustin.me/2021/02/wired-sculpt/
AntiRush · 2018-07-05
I've found that most scripts can/should belong to a specific project.
We've started adopting the `s/` method described here by Chad Austin: https://chadaustin.me/2017/01/s/.
It means you always know where to look and it's easy to see what scripts exist.
ricardobeat · 2017-12-10
As usual, it depends. See https://chadaustin.me/wp-uploads/perf-msvc-haswell.png
RossBencina · 2016-10-02
I'd not heard of tup, thought I'd try it out on Windows. Unfortunately I hit a bug straight away: Tup is not directly compatible with MSVC 2015 (without disabling VCToolsTelemetry.dat generation in the registry) [0].
I don't fancy adopting a tool that forces me to opt-out of being able to send compiler debug telemetry to Microsoft the next time I hit a compiler bug.
There is a nice (but a bit dated, 2010) review here [1] which discusses some other features and shortcomings.
[0] https://github.com/gittup/tup/issues/182
[1] 2010: https://chadaustin.me/2010/06/scalable-build-systems-an-analysis-of-tu…
Mathnerd314 · 2016-06-05
Any imperative algorithm / data-structure, e.g. union-find, can be implemented purely by using an IntMap for memory and a State monad, with roughly equivalent performance: https://hackage.haskell.org/package/union-find
As to whether that actually counts as "purely functional programming", I can't say. Honestly the whole term seems quite misleading. https://chadaustin.me/2015/09/haskell-is-not-a-purely-functional-langu…
TimothyFitz · 2011-02-06
This is the exact reason why Chad Austin started working on ibb (I/O-Bound-Build): http://chadaustin.me/2010/03/your-version-control-and-build-systems-do…
redbeeswimming · 2025-12-26
> The website prioritizes programs with 98% safe code over programs with 0% safe code.
Please explain this section of the Rustonomicon.
https://doc.rust-lang.org/nomicon/working-with-unsafe.html
> This code is 100% Safe Rust but it is also completely unsound. Changing the capacity violates the invariants of Vec (that cap reflects the allocated space in the Vec). This is not something the rest of Vec can guard against. It has to trust the capacity field because there's no way to verify it.
> Because it relies on invariants of a struct field, this unsafe code does more than pollute a whole function: it pollutes a whole module. Generally, the only bullet-proof way to limit the scope of unsafe code is at the module boundary with privacy.
If 2% code means that, wildly spitballing, 50% code has to be manually reviewed, it's not quite as impressive.
And it might be worse regarding memory safety than the "status quo" if one accepts the assumption that unsafe Rust is harder than C and C++, as many Rust developers do.
https://www.reddit.com/r/rust/comments/1amlfdj/comment/kpmb2b8/
> It may be even less safe because of the strong aliasing rules. That is, it may be harder to write correct unsafe {} Rust than correct C. Only use unsafe {} when absolutely needed.
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
vlovich123 · 2025-10-25
https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
https://news.ycombinator.com/item?id=41944121
The TLDR is that there’s all sorts of invariants that the Rust compiler internals assume about Rust code (eg pointers don’t alias). In C such assumptions can’t be made. Unsafe rust requires you to uphold all the same invariants that safe rust does without any guardrails and it has more such assumptions than C. C however is uniformly dangerous - there isn’t a safe subset to write your code in.
One example would be that you could have something like:
let x = 5; do_something(&x as *const _ as *mut _); Now do_something might dereference and write to the pointer. Now you have non-local safety to reason about because if the compiler realizes you’ve tried to dereference a mutable pointer to an immutable variable it’s free to declare that UB and do bad unsound things (the non-locality is because the unsafe is inside do_something but the problem is with the pointer cast in safe rust). There’s all sorts of subtle things like that.
trealira · 2025-05-17
> Choosing references as your default is insane, honestly. Safe Rust is akin to writing formally verified software in the mental and ergonomic overhead it incurs. That's not coincidental. I've come to the conclusion one of the biggest mistakes of the community is not pushing pointer-only Rust harder, given they want it to be taken seriously as a systems language.
That's an interesting perspective I hadn't heard before, but I think there are a couple problems. One, the culture is really against using unsafe unless it's impossible to write the code using safe Rust. This happened with the Actix web drama in 2020 [1]. And, there is the opinion that unsafe Rust is harder than C [2]. Not just that, but unsafe Rust is really ugly and annoying to use compared to safe Rust. I think that hinders the potential adoption of your idea, too.
[1]: https://steveklabnik.com/writing/a-sad-day-for-rust/
[2]: https://chadaustin.me/2024/10/intrusive-linked-list-in-rust/
estebank · 2020-10-20
I do not have any non-Rust resources off the top of my head, but I can give you some quickly looked up resources and enough phrases to search for that should help you in this endeavor.
ADTs are Abstract Data Types[1][2][3]:
> ADT is implementation independent. For example, it only describes what a data type List consists (data) and what are the operations it can perform, but it has no information about how the List is actually implemented.
In the context of Rust it means that the traits, structs and enums are ADTs, while the impls are Data Structures.
Having structs and enums be the way they are in Rust (simplistic and with little extensibility beyond implementing traits) is that pattern matching[4][5] and destructuring is cheap and built in. Pattern matching becomes specially useful when combined with sum types/tagged unions/enums[6][7][8]. On the other corner you have Scala which lets you implement specific interfaces to allow structuring and destructuring for arbitrary types, but that has the same problems as overriding constructors in C++: the performance implications of pattern matching is impl dependent and hidden at the point of calling.
[1]: https://softwareengineering.stackexchange.com/questions/148747/abstrac…
[2]: https://en.wikipedia.org/wiki/Abstract_data_type
[3]: https://abrickshort.wordpress.com/2005/03/06/abstract-data-types-vs-da…
[4]: https://en.wikipedia.org/wiki/Pattern_matching
[5]:…