Speed up big chainspec json(~1.5 GB) load (#10137)

* Speed up chainspec json load

* Update client/chain-spec/src/chain_spec.rs

* Update client/chain-spec/src/chain_spec.rs

* Update client/chain-spec/src/chain_spec.rs

* Load the chainspec through `mmap`

Co-authored-by: icodezjb <icodezjb@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Jan Bujak <jan@parity.io>
This commit is contained in:
icodezjb
2021-11-01 20:58:18 +08:00
committed by GitHub
parent 710265a4f8
commit 7f1bff9462
3 changed files with 25 additions and 4 deletions
+13 -3
View File
@@ -1648,7 +1648,7 @@ checksum = "42276e3f205fe63887cca255aa9a65a63fb72764c30b9a6252a7c7e46994f689"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"dynasm", "dynasm",
"memmap2", "memmap2 0.2.1",
] ]
[[package]] [[package]]
@@ -4097,6 +4097,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "memmap2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4647a11b578fead29cdbb34d4adef8dd3dc35b876c9c6d5240d83f205abfe96e"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.6.4" version = "0.6.4"
@@ -6174,7 +6183,7 @@ dependencies = [
"libc", "libc",
"log 0.4.14", "log 0.4.14",
"lz4", "lz4",
"memmap2", "memmap2 0.2.1",
"parking_lot 0.11.1", "parking_lot 0.11.1",
"rand 0.8.4", "rand 0.8.4",
"snap", "snap",
@@ -7503,6 +7512,7 @@ name = "sc-chain-spec"
version = "4.0.0-dev" version = "4.0.0-dev"
dependencies = [ dependencies = [
"impl-trait-for-tuples", "impl-trait-for-tuples",
"memmap2 0.5.0",
"parity-scale-codec", "parity-scale-codec",
"sc-chain-spec-derive", "sc-chain-spec-derive",
"sc-network", "sc-network",
@@ -11285,7 +11295,7 @@ dependencies = [
"backtrace", "backtrace",
"bincode", "bincode",
"lazy_static", "lazy_static",
"memmap2", "memmap2 0.2.1",
"more-asserts", "more-asserts",
"rustc-demangle", "rustc-demangle",
"serde", "serde",
+1
View File
@@ -22,3 +22,4 @@ serde_json = "1.0.68"
sp-runtime = { version = "4.0.0-dev", path = "../../primitives/runtime" } sp-runtime = { version = "4.0.0-dev", path = "../../primitives/runtime" }
sc-telemetry = { version = "4.0.0-dev", path = "../telemetry" } sc-telemetry = { version = "4.0.0-dev", path = "../telemetry" }
codec = { package = "parity-scale-codec", version = "2.0.0" } codec = { package = "parity-scale-codec", version = "2.0.0" }
memmap2 = "0.5.0"
+11 -1
View File
@@ -285,10 +285,20 @@ impl<G, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
/// Parse json file into a `ChainSpec` /// Parse json file into a `ChainSpec`
pub fn from_json_file(path: PathBuf) -> Result<Self, String> { pub fn from_json_file(path: PathBuf) -> Result<Self, String> {
// We mmap the file into memory first, as this is *a lot* faster than using
// `serde_json::from_reader`. See https://github.com/serde-rs/json/issues/160
let file = File::open(&path) let file = File::open(&path)
.map_err(|e| format!("Error opening spec file `{}`: {}", path.display(), e))?; .map_err(|e| format!("Error opening spec file `{}`: {}", path.display(), e))?;
// SAFETY: `mmap` is fundamentally unsafe since technically the file can change
// underneath us while it is mapped; in practice it's unlikely to be a problem
let bytes = unsafe {
memmap2::Mmap::map(&file)
.map_err(|e| format!("Error mmaping spec file `{}`: {}", path.display(), e))?
};
let client_spec = let client_spec =
json::from_reader(file).map_err(|e| format!("Error parsing spec file: {}", e))?; json::from_slice(&bytes).map_err(|e| format!("Error parsing spec file: {}", e))?;
Ok(ChainSpec { client_spec, genesis: GenesisSource::File(path) }) Ok(ChainSpec { client_spec, genesis: GenesisSource::File(path) })
} }
} }