4 ms·
Why is stdout faster than stderr?
- 48864w6ui 3y agoToo bad TFA started from rust instead of c; this behavior is all explained (in fewer words) in K&R.
- mechanicker 3y agoThis is my exact concern when new corp of developers try and learn operating systems using languages further away from the building blocks. Unpopular opinion: It is still good to learn enough C + system programming & their gotchas before starting with a more fancy higher level language.
- lijok 3y ago> Unpopular opinion: It is still good to learn enough C + system programming & their gotchas before starting with a more fancy higher level language. And easier
- tester756 3y agoIs going from high level to low level somehow worse? I went from very high level (C# web and even webassembly) to C and while I believe I learned a lot and my understanding of computers improved, then I think the biggest lesson is that one of the most important programming ecosystems (C) is a very messy and painful. Not because it must be painful, but because of decisions made decades ago, maybe some inertia, maybe backward compatibility, maybe culture, who knows? Low quality compiler messages, ecosystem fragmentation, terrible standard lib (where are my basic datastructures), memory management being minefield, etc.
- edgyquant 3y agoC gets a bad wrap because there are now alternatives built by finding solutions to problems we only know because of Cs existence. Compiler messages, standard library and memory management are all things we can agree are terrible now days but when C came out it was a huge improvement over the norms before. Also it’s important to remember even “big” things like Unix were at one point just a few thousand lines of code.
- danielvaughn 3y agoAfter being a web developer for 10+ years, I'm getting into C for the first time. I'd had a bit of experience with Objective-C years ago when I did some iOS work, but that was the "lowest" I'd gone down the stack. There's a lot of unfamiliar territory, but I'm really enjoying it. When it's complex, it feels like it's just inherently complex. Which is a breath of fresh air for a web developer. I'd gotten so sick of the bullshit complexity that comes along with the high-level work; programming feels fun again.
- junon 3y agoRust full-timer with a background in C/C++, lately using neither at all. That opinion isn't as unpopular as you'd think.
- fl0ki 3y agoI don't think this is a fair comparison. If you want to teach that you can write(2) to raw FDs in Rust, you can, just like you can use write(2) or fprintf(3) in C. C has a standard library which students should understand even though it's making system calls deep down. Rust has a standard library which students should understand even though it's making system calls deep down (in fact, sometimes through the host C library). I certainly see the value in knowing C and Unix and that was my education over two decades ago as well. But I also watched many people quit computer science altogether because they struggled with heisenbugs with C pointers. If they could have been kept on track by Rust compiler errors and higher level abstractions, maybe they would still be in the industry today, learning whatever else they needed instead of quitting in their first semester.
- loeg 3y agoThis behavior could be explained in a lot fewer words in a Rust tutorial, too. The investigation itself is kind of interesting and learning to use profiling tools is valuable. It's still more verbose than my preference, and I don't love the style. Still. This and K&R are very different kinds of material.
- satiated_grue 3y agohttps://linux.die.net/man/3/stderr https://linux.die.net/man/3/stderr Notes The stream stderr is unbuffered. The stream stdout is line-buffered when it points to a terminal. Partial lines will not appear until fflush(3) or exit(3) is called, or a newline is printed. This can produce unexpected results, especially with debugging output. The buffering mode of the standard streams (or any other stream) can be changed using the setbuf(3) or setvbuf(3) call. Note that in case stdin is associated with a terminal, there may also be input buffering in the terminal driver, entirely unrelated to stdio buffering. (Indeed, normally terminal input is line buffered in the kernel.) This kernel input handling can be modified using calls like tcsetattr(3); see also stty(1), and termios(3).
- nerdponx 3y agoIs this a Linux implementation detail, or is it a feature of POSIX systems generally?
- thesuitonym 3y agoOpenBSD's stderr seems to be buffered, so it may just be a Linux thing. https://man.openbsd.org/stdio.3 https://man.openbsd.org/stdio.3
- loeg 3y agoThat page says the opposite: > Initially, the standard error stream is unbuffered.
- thesuitonym 3y agoI have no idea how I read that so wrong. Mea culpa.
- loeg 3y agoPOSIX says that stderr shouldn't be "fully buffered" https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/s... but I believe that allows for line buffering. Its terminology can be found here: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/st... (look for _IOFBF).
- rwmj 3y agoA lot of words. Is it because of line buffering? coreutils has a very hairy program called stdbuf which can change the line buffering of an existing program. It uses LD_PRELOAD(!) to preload a library which overrides the program's defaults.
- deleted 3y ago[deleted]
- loeg 3y agoThe short version is yeah. Rust line-buffers stdout but not stderr, for no particularly good reason.
- epcoa 3y ago> In Unix, character special files are files that access to I/O devices such as a NULL file (/dev/null) and file descriptors. In our case, stdout is a file descriptor (1) so it is a character special file. (The name "character special" actually comes from the fact that each character is handled individually.) Ummm no. This is completely backwards. Stdout isn’t character special if it is pointing to a disk file. And they are hung up on a Linuxism here to boot (the proc symlink). The whole world isn’t Linux and I have never heard of this definition of character special, so I wonder where they found it. Of note, FreeBSD realized the whole block/character distinction was dumb, even block device modes are “character special”. Author is very confused about the ontology of file descriptors and files, and device nodes. Sure it’s confusing to a newcomer but there are plenty of well written guides on the topic. Too verbose, too Linux centric and too inaccurate. And scrolling through nothing new than what is well trodden ground https://stackoverflow.com/questions/37991116/why-is-stdout-buffering https://stackoverflow.com/questions/37991116/why-is-stdout-b... Tl fucking dr, stderr is not buffered by default in rust.
- edgyquant 3y agoThis comment seems extremely aggressive and I’d add that most of the world is, in fact, Linux.
- epcoa 3y ago> at most of the world is, in fact, Linux. Yeah, other than the most popular Unix like desktop OS being macOS and iOS a dominant second in mobile. Other than those two that no one uses, most of the world is Linux. And for the topic at hand the macOS design is basically same as FreeBSD as mentioned, macOS is not derived from Linux.
- edgyquant 3y agoMost computers are not desktops. Most phones and servers are Linux based, thus the overwhelming majority of computers are running Linux.
- weinzierl 3y agoDoes it say somewhere why in Rust one is buffered and the other is not?
- loeg 3y agoBoth (line-buffered stdout, raw stderr) date to the initial implementation 10 years ago: https://github.com/rust-lang/rust/commit/94d71f8836b3bfac3370e4d324ca1987d843552f https://github.com/rust-lang/rust/commit/94d71f8836b3bfac337... . The commit message mentions that stderr is no longer buffered (probably as a result of the RFC 899 discussion, which I cannot seem to locate).
- weinzierl 3y agoThanks for digging this up! It is good and interesting info, but unfortunately still doesn't satisfactorily answer why they are treated differently.
- loeg 3y agoI did some more digging. By RFC 899, I believe Alex Crichton meant PR 899 in this repo: https://github.com/rust-lang/rfcs/pull/899 https://github.com/rust-lang/rfcs/pull/899 Still, no real discussion of why unbuffered stderr.
- masklinn 3y agoBecause stderr being conventionally used for error reporting it's important to immediately output that information to avoid losing it in case the program then crashes or ends without flushing. Stdout is generally the "normal output" so loss of information on crash tends to be less relevant, and throughput more so as programs commonly send huge amounts of data to stdout.
- helsinkiandrew 3y agoI thought this is a general unix thing. stdout is buffered so output to other apps/terminal is efficient, whilst stderr isn’t buffered because it’s usually to the console with (smaller) error messages that should be seen immediately in case of app crashes etc.
- loeg 3y agoPOSIX only specifies that stderr in C programs isn't block ("fully") buffered by default. I believe it allows for line buffering. https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/s... POSIX doesn't govern Rust at all.
- mr_vile 3y agoIt would have been more honest to add (in Rust) to the title.