Skip to content

Conversation

timvisee
Copy link
Member

@timvisee timvisee commented May 9, 2025

When reading from or writing to files, we must buffer IO. If we don't we waste a lot of syscalls. Syscalls are expensive because they trigger a context switch.

Lets take reading raft_state.json as example.

Before - yes I'm not kidding - we had 416 syscalls:

Click to expand
openat(AT_FDCWD, "./storage/raft_state.json", O_RDONLY|O_CLOEXEC) = 3
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "h", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "v", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "9", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "7", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "8", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "c", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "2", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "c", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "f", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "v", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "[", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "9", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "7", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "8", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "]", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "l", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "[", 1)                         = 1
read(3, "]", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "v", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "u", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "g", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "g", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "[", 1)                         = 1
read(3, "]", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "l", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "x", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "[", 1)                         = 1
read(3, "]", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "a", 1)                         = 1
read(3, "u", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "l", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "v", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "f", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "l", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "l", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "h", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "i", 1)                         = 1
read(3, "n", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "x", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "a", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, "l", 1)                         = 1
read(3, "y", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "g", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "q", 1)                         = 1
read(3, "u", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "u", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "[", 1)                         = 1
read(3, "3", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "2", 1)                         = 1
read(3, "]", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "f", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "v", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "9", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "7", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "8", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "p", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "b", 1)                         = 1
read(3, "y", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "4", 1)                         = 1
read(3, "9", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "7", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "8", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "h", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, ":", 1)                         = 1
read(3, "/", 1)                         = 1
read(3, "/", 1)                         = 1
read(3, "l", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "c", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "l", 1)                         = 1
read(3, "h", 1)                         = 1
read(3, "o", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, ":", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "3", 1)                         = 1
read(3, "3", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "/", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "}", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "p", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "m", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "t", 1)                         = 1
read(3, "a", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "b", 1)                         = 1
read(3, "y", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "{", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, ",", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, "t", 1)                         = 1
read(3, "h", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "s", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "p", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "e", 1)                         = 1
read(3, "r", 1)                         = 1
read(3, "_", 1)                         = 1
read(3, "i", 1)                         = 1
read(3, "d", 1)                         = 1
read(3, "\"", 1)                        = 1
read(3, ":", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "9", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "7", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "5", 1)                         = 1
read(3, "8", 1)                         = 1
read(3, "0", 1)                         = 1
read(3, "6", 1)                         = 1
read(3, "1", 1)                         = 1
read(3, "4", 1)                         = 1
read(3, "}", 1)                         = 1
read(3, "", 1)                          = 0

After we just have 3:

Click to expand
openat(AT_FDCWD, "./storage/raft_state.json", O_RDONLY|O_CLOEXEC) = 3
read(3, "{\"state\":{\"hard_state\":{\"term\":2"..., 8192) = 414
read(3, "", 8192)                       = 0

This with the default state on a single node cluster. The bigger your cluster gets, the more significant the difference will be.

All Submissions:

  • Contributions should target the dev branch. Did you create your branch from dev?
  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. Does your submission pass tests?
  2. Have you formatted your code locally using cargo +nightly fmt --all command prior to submission?
  3. Have you checked your code using cargo clippy --all --all-features command?

@generall generall marked this pull request as ready for review May 9, 2025 12:52
@generall generall self-requested a review May 9, 2025 12:52

This comment was marked as resolved.

Copy link
Member

@KShivendu KShivendu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow. I had learnt difference between BufReader and File while trying 1 billion rows challenge but didn't know that we missed it in core. Great find!

@timvisee
Copy link
Member Author

timvisee commented May 9, 2025

Yeah it usually isn't obvious it's missing.

In some places documentation explicitly states to use it, like: https://docs.rs/serde_json/latest/serde_json/fn.from_reader.html

@timvisee timvisee merged commit 833f310 into dev May 9, 2025
17 checks passed
@timvisee timvisee deleted the buffer-file-io branch May 9, 2025 13:48
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.

4 participants