file_storage: Wrap `File` in `BufWriter` (#3353)

When exiting my application, it would freeze for around a minute waiting to finish writing ca. 40MB to file storage.
Some quick profiling revealed that it was spending all that time in `File::write`,
presumably making a large number of system calls writing tiny amounts of data at a time.
We can avoid this by buffering writes using a `BufWriter`, just like we already do with `BufReader`.

With this change, my application takes around 1-2 seconds to exit, with the majority of that time spent serializing `ron`.
I'm sure there are further potential performance improvements there, but this is already an order of magnitude or two better.

I also fixed the call to `log::warn!`, which was using incorrect formatting syntax and not including the error message.
This commit is contained in:
Sebastian Reinhard 2023-09-18 16:40:29 +02:00 committed by GitHub
parent 8073ca6fe0
commit 433d1fc239
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 2 deletions

View File

@ -1,5 +1,6 @@
use std::{
collections::HashMap,
io::Write,
path::{Path, PathBuf},
};
@ -126,10 +127,13 @@ fn save_to_disk(file_path: &PathBuf, kv: &HashMap<String, String>) {
match std::fs::File::create(file_path) {
Ok(file) => {
let mut writer = std::io::BufWriter::new(file);
let config = Default::default();
if let Err(err) = ron::ser::to_writer_pretty(file, &kv, config) {
log::warn!("Failed to serialize app state: {err}");
if let Err(err) = ron::ser::to_writer_pretty(&mut writer, &kv, config)
.and_then(|_| writer.flush().map_err(|err| err.into()))
{
log::warn!("Failed to serialize app state: {}", err);
} else {
log::trace!("Persisted to {:?}", file_path);
}