Skip to content

Commit dc7cb2a

Browse files
bushrat011899cart
andauthored
Switch to ImDocument in BevyManifest (#18272)
# Objective When reviewing #18263, I noticed that `BevyManifest` internally stores a `DocumentMut`, a mutable TOML document, instead of an `ImDocument`, an immutable one. The process of creating a `DocumentMut` first involves creating a `ImDocument` and then cloning all the referenced spans of text into their own allocations (internally referred to as `despan` in `toml_edit`). As such, using a `DocumentMut` without mutation is strictly additional overhead. In addition, I noticed that the filesystem operations associated with reading a manifest and parsing it were written to be completed _while_ a write-lock was held on `MANIFESTS`. This likely doesn't translate into a performance or deadlock issue as the manifest files are generally small and can be read quickly, but it is generally considered a bad practice. ## Solution - Switched to `ImDocument<Box<str>>` instead of `DocumentMut` - Re-ordered operations in `BevyManifest::shared` to minimise time spent holding open the write-lock on `MANIFESTS` ## Testing - CI --- ## Notes I wasn't able to measure a meaningful performance difference with this PR, so this is purely a code quality change and not one for performance. --------- Co-authored-by: Carter Anderson <mcanders1@gmail.com>
1 parent 81c0900 commit dc7cb2a

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

crates/bevy_macro_utils/src/bevy_manifest.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use std::{
88
path::{Path, PathBuf},
99
time::SystemTime,
1010
};
11-
use toml_edit::{DocumentMut, Item};
11+
use toml_edit::{ImDocument, Item};
1212

1313
/// The path to the `Cargo.toml` file for the Bevy project.
1414
#[derive(Debug)]
1515
pub struct BevyManifest {
16-
manifest: DocumentMut,
16+
manifest: ImDocument<Box<str>>,
1717
modified_time: SystemTime,
1818
}
1919

@@ -34,14 +34,15 @@ impl BevyManifest {
3434
return manifest;
3535
}
3636
}
37+
38+
let manifest = BevyManifest {
39+
manifest: Self::read_manifest(&manifest_path),
40+
modified_time,
41+
};
42+
43+
let key = manifest_path.clone();
3744
let mut manifests = MANIFESTS.write();
38-
manifests.insert(
39-
manifest_path.clone(),
40-
BevyManifest {
41-
manifest: Self::read_manifest(&manifest_path),
42-
modified_time,
43-
},
44-
);
45+
manifests.insert(key, manifest);
4546

4647
RwLockReadGuard::map(RwLockWriteGuard::downgrade(manifests), |manifests| {
4748
manifests.get(&manifest_path).unwrap()
@@ -69,11 +70,11 @@ impl BevyManifest {
6970
std::fs::metadata(cargo_manifest_path).and_then(|metadata| metadata.modified())
7071
}
7172

72-
fn read_manifest(path: &Path) -> DocumentMut {
73+
fn read_manifest(path: &Path) -> ImDocument<Box<str>> {
7374
let manifest = std::fs::read_to_string(path)
74-
.unwrap_or_else(|_| panic!("Unable to read cargo manifest: {}", path.display()));
75-
manifest
76-
.parse::<DocumentMut>()
75+
.unwrap_or_else(|_| panic!("Unable to read cargo manifest: {}", path.display()))
76+
.into_boxed_str();
77+
ImDocument::parse(manifest)
7778
.unwrap_or_else(|_| panic!("Failed to parse cargo manifest: {}", path.display()))
7879
}
7980

0 commit comments

Comments
 (0)