2 ms·
The FreeBSD version is building up an iovec (which is effectively an array of (pointer, length) tuples) to pass to writev. I believe this is done for two reason
by lcampbell 14y ago
The FreeBSD version is building up an iovec (which is effectively an array of (pointer, length) tuples) to pass to writev. I believe this is done for two reasons --
1) It reduces the number of syscalls -- a single call to writev outputs everything, rather than multiple fputs calls which may or may not be buffered (I haven't checked the impl details of fputs).
2) It reduces the number of allocations. Since an iovec is just an array of pointers, we can reused the data passed in via argv; the length of the iovec is capped at argc, so we can get away with one allocation without scanning the input.
For a comparison, here's a brief overview of each of the implementations (assuming fprint/fputs is not buffered):
* Unix V5: 0 allocations, N syscalls, no argv scan
* OpenBSD: 0 allocations, N syscalls, no argv scan
* Plan 9: 1 allocation, 1 syscall, scans argv
* FreeBSD: 1 allocation, 1 syscall, no argv scan
* GNU (without -e): 0 allocations, N syscalls, no argv scan
"argv scan" basically means calling strlen on every passed argument, or otherwise iterating over them. Naturally, "which one is faster" depends on how fast your allocations/syscalls/strlen's are, and how fprint/fputs is buffered.