Skip to content

Commit

Permalink
perf: replace RawSource with smaller RawStringSource and `RawBuff…
Browse files Browse the repository at this point in the history
…erSource` (#8629)

* perf: smaller `RawSource` with `RawStringSource` and `RawBufferSource`

* feat: more

* feat: test
  • Loading branch information
h-a-n-a authored Dec 5, 2024
1 parent 8b0f43f commit 2c097de
Show file tree
Hide file tree
Showing 115 changed files with 515 additions and 420 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ rayon = { version = "1.10.0" }
regex = { version = "1.11.1" }
ropey = "1.6.1"
rspack_resolver = { version = "0.3.5", features = ["package_json_raw_json_api"] }
rspack_sources = { version = "=0.3.5" }
rspack_sources = { version = "=0.3.6" }
rustc-hash = { version = "1.1.0" }
serde = { version = "1.0.215" }
serde_json = { version = "1.0.133" }
Expand Down
83 changes: 74 additions & 9 deletions crates/rspack_binding_values/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use std::{hash::Hash, sync::Arc};

use napi_derive::napi;
use rspack_core::rspack_sources::{
BoxSource, CachedSource, ConcatSource, MapOptions, OriginalSource, RawSource, ReplaceSource,
Source, SourceExt, SourceMap, SourceMapSource, WithoutOriginalOptions,
BoxSource, CachedSource, ConcatSource, MapOptions, OriginalSource, RawBufferSource, RawSource,
RawStringSource, ReplaceSource, Source, SourceExt, SourceMap, SourceMapSource,
WithoutOriginalOptions,
};
use rspack_napi::napi::bindgen_prelude::*;

Expand All @@ -30,13 +31,13 @@ impl<'s> From<JsCompatSource<'s>> for BoxSource {
source_map,
})
.boxed(),
None => RawSource::from(string).boxed(),
None => RawStringSource::from(string).boxed(),
}
} else {
RawSource::from(string).boxed()
RawStringSource::from(string).boxed()
}
}
Either::B(buffer) => RawSource::from(buffer.to_vec()).boxed(),
Either::B(buffer) => RawBufferSource::from(buffer.to_vec()).boxed(),
}
}
}
Expand All @@ -60,13 +61,13 @@ impl From<JsCompatSourceOwned> for BoxSource {
source_map,
})
.boxed(),
None => RawSource::from(string).boxed(),
None => RawStringSource::from(string).boxed(),
}
} else {
RawSource::from(string).boxed()
RawStringSource::from(string).boxed()
}
}
Either::B(buffer) => RawSource::from(Vec::<u8>::from(buffer)).boxed(),
Either::B(buffer) => RawBufferSource::from(Vec::<u8>::from(buffer)).boxed(),
}
}
}
Expand All @@ -88,6 +89,24 @@ impl ToJsCompatSource for RawSource {
}
}

impl ToJsCompatSource for RawBufferSource {
fn to_js_compat_source(&self, env: &Env) -> Result<JsCompatSource> {
Ok(JsCompatSource {
source: Either::B(BufferSlice::from_data(env, self.buffer())?),
map: to_webpack_map(self)?,
})
}
}

impl ToJsCompatSource for RawStringSource {
fn to_js_compat_source(&self, _env: &Env) -> Result<JsCompatSource> {
Ok(JsCompatSource {
source: Either::A(self.source().to_string()),
map: to_webpack_map(self)?,
})
}
}

impl<T: Source + Hash + PartialEq + Eq + 'static> ToJsCompatSource for ReplaceSource<T> {
fn to_js_compat_source(&self, env: &Env) -> Result<JsCompatSource> {
Ok(JsCompatSource {
Expand Down Expand Up @@ -136,8 +155,22 @@ impl ToJsCompatSource for dyn Source + '_ {
fn to_js_compat_source(&self, env: &Env) -> Result<JsCompatSource> {
if let Some(raw_source) = self.as_any().downcast_ref::<RawSource>() {
raw_source.to_js_compat_source(env)
} else if let Some(raw_string) = self.as_any().downcast_ref::<RawStringSource>() {
raw_string.to_js_compat_source(env)
} else if let Some(raw_buffer) = self.as_any().downcast_ref::<RawBufferSource>() {
raw_buffer.to_js_compat_source(env)
} else if let Some(cached_source) = self.as_any().downcast_ref::<CachedSource<RawSource>>() {
cached_source.to_js_compat_source(env)
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<RawStringSource>>()
{
cached_source.to_js_compat_source(env)
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<RawBufferSource>>()
{
cached_source.to_js_compat_source(env)
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<Box<dyn Source>>>()
Expand All @@ -153,7 +186,7 @@ impl ToJsCompatSource for dyn Source + '_ {
} else if let Some(source) = self.as_any().downcast_ref::<Arc<dyn Source>>() {
source.to_js_compat_source(env)
} else {
// If it's not a `RawSource` related type, then we regards it as a `Source` type.
// If it's not a `RawStringSource` related type, then we regards it as a `Source` type.
Ok(JsCompatSource {
source: Either::A(self.source().to_string()),
map: to_webpack_map(self)?,
Expand All @@ -179,6 +212,24 @@ impl ToJsCompatSourceOwned for RawSource {
}
}

impl ToJsCompatSourceOwned for RawBufferSource {
fn to_js_compat_source_owned(&self) -> Result<JsCompatSourceOwned> {
Ok(JsCompatSourceOwned {
source: Either::B(self.buffer().to_vec().into()),
map: to_webpack_map(self)?,
})
}
}

impl ToJsCompatSourceOwned for RawStringSource {
fn to_js_compat_source_owned(&self) -> Result<JsCompatSourceOwned> {
Ok(JsCompatSourceOwned {
source: Either::A(self.source().to_string()),
map: to_webpack_map(self)?,
})
}
}

impl<T: Source + Hash + PartialEq + Eq + 'static> ToJsCompatSourceOwned for ReplaceSource<T> {
fn to_js_compat_source_owned(&self) -> Result<JsCompatSourceOwned> {
Ok(JsCompatSourceOwned {
Expand Down Expand Up @@ -227,8 +278,22 @@ impl ToJsCompatSourceOwned for dyn Source + '_ {
fn to_js_compat_source_owned(&self) -> Result<JsCompatSourceOwned> {
if let Some(raw_source) = self.as_any().downcast_ref::<RawSource>() {
raw_source.to_js_compat_source_owned()
} else if let Some(raw_string) = self.as_any().downcast_ref::<RawStringSource>() {
raw_string.to_js_compat_source_owned()
} else if let Some(raw_buffer) = self.as_any().downcast_ref::<RawBufferSource>() {
raw_buffer.to_js_compat_source_owned()
} else if let Some(cached_source) = self.as_any().downcast_ref::<CachedSource<RawSource>>() {
cached_source.to_js_compat_source_owned()
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<RawStringSource>>()
{
cached_source.to_js_compat_source_owned()
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<RawBufferSource>>()
{
cached_source.to_js_compat_source_owned()
} else if let Some(cached_source) = self
.as_any()
.downcast_ref::<CachedSource<Box<dyn Source>>>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rkyv::{
Archive, Archived, Deserialize, Place, Resolver, Serialize,
};
use rspack_sources::{
BoxSource, RawSource, Source, SourceExt, SourceMap, SourceMapSource, WithoutOriginalOptions,
BoxSource, RawBufferSource, Source, SourceExt, SourceMap, SourceMapSource, WithoutOriginalOptions,
};

use super::AsPreset;
Expand Down Expand Up @@ -81,6 +81,6 @@ where
);
}
}
Ok(RawSource::from(buffer).boxed())
Ok(RawBufferSource::from(buffer).boxed())
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rspack_cacheable::{cacheable, from_bytes, to_bytes, with::AsPreset};
use rspack_sources::{BoxSource, RawSource, SourceExt};
use rspack_sources::{BoxSource, RawBufferSource, RawStringSource, SourceExt};

#[cacheable]
#[derive(Debug)]
Expand All @@ -17,6 +17,6 @@ fn test_rspack_source() {
);
}

test_data(Data(RawSource::from("123".as_bytes()).boxed()));
test_data(Data(RawSource::from_static("123").boxed()));
test_data(Data(RawBufferSource::from("123".as_bytes()).boxed()));
test_data(Data(RawStringSource::from_static("123").boxed()));
}
32 changes: 17 additions & 15 deletions crates/rspack_core/src/concatenated_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use rspack_collections::{
use rspack_error::{Diagnosable, Diagnostic, DiagnosticKind, Result, TraceableError};
use rspack_hash::{HashDigest, HashFunction, RspackHash};
use rspack_hook::define_hook;
use rspack_sources::{CachedSource, ConcatSource, RawSource, ReplaceSource, Source, SourceExt};
use rspack_sources::{
CachedSource, ConcatSource, RawStringSource, ReplaceSource, Source, SourceExt,
};
use rspack_util::{ext::DynHash, itoa, source_map::SourceMapKind, swc::join_atom};
use rustc_hash::FxHasher;
use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
Expand Down Expand Up @@ -1022,15 +1024,15 @@ impl Module for ConcatenatedModule {
runtime_requirements.insert(RuntimeGlobals::DEFINE_PROPERTY_GETTERS);

if should_add_esm_flag {
result.add(RawSource::from_static("// ESM COMPAT FLAG\n"));
result.add(RawSource::from(define_es_module_flag_statement(
result.add(RawStringSource::from_static("// ESM COMPAT FLAG\n"));
result.add(RawStringSource::from(define_es_module_flag_statement(
self.get_exports_argument(),
&mut runtime_requirements,
)));
}

result.add(RawSource::from_static("\n// EXPORTS\n"));
result.add(RawSource::from(format!(
result.add(RawStringSource::from_static("\n// EXPORTS\n"));
result.add(RawStringSource::from(format!(
"{}({}, {{{}\n}});\n",
RuntimeGlobals::DEFINE_PROPERTY_GETTERS,
exports_argument,
Expand All @@ -1041,7 +1043,7 @@ impl Module for ConcatenatedModule {

// List unused exports
if !unused_exports.is_empty() {
result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"\n// UNUSED EXPORTS: {}\n",
join_atom(unused_exports.iter(), ", ")
)));
Expand Down Expand Up @@ -1163,7 +1165,7 @@ impl Module for ConcatenatedModule {
};

if let Some(source) = namespace_object_sources.get(&info.module) {
result.add(RawSource::from(source.as_str()));
result.add(RawStringSource::from(source.as_str()));
}
}

Expand All @@ -1184,7 +1186,7 @@ impl Module for ConcatenatedModule {

match info {
ModuleInfo::Concatenated(info) => {
result.add(RawSource::from(
result.add(RawStringSource::from(
format!(
"\n;// CONCATENATED MODULE: {}\n",
module_readable_identifier
Expand All @@ -1202,7 +1204,7 @@ impl Module for ConcatenatedModule {
name = info.namespace_object_name.clone();
}
ModuleInfo::External(info) => {
result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"\n// EXTERNAL MODULE: {}\n",
module_readable_identifier
)));
Expand All @@ -1220,10 +1222,10 @@ impl Module for ConcatenatedModule {

if condition != "true" {
is_conditional = true;
result.add(RawSource::from(format!("if ({}) {{\n", condition)));
result.add(RawStringSource::from(format!("if ({}) {{\n", condition)));
}

result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"var {} = {}({});",
info.name.as_ref().expect("should have name"),
RuntimeGlobals::REQUIRE,
Expand All @@ -1240,7 +1242,7 @@ impl Module for ConcatenatedModule {

if info.get_interop_namespace_object_used() {
runtime_requirements.insert(RuntimeGlobals::CREATE_FAKE_NAMESPACE_OBJECT);
result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"\nvar {} = /*#__PURE__*/{}({}, 2);",
info
.get_interop_namespace_object_name()
Expand All @@ -1252,7 +1254,7 @@ impl Module for ConcatenatedModule {

if info.get_interop_namespace_object2_used() {
runtime_requirements.insert(RuntimeGlobals::CREATE_FAKE_NAMESPACE_OBJECT);
result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"\nvar {} = /*#__PURE__*/{}({});",
info
.get_interop_namespace_object2_name()
Expand All @@ -1264,7 +1266,7 @@ impl Module for ConcatenatedModule {

if info.get_interop_default_access_used() {
runtime_requirements.insert(RuntimeGlobals::COMPAT_GET_DEFAULT_EXPORT);
result.add(RawSource::from(format!(
result.add(RawStringSource::from(format!(
"\nvar {} = /*#__PURE__*/{}({});",
info
.get_interop_default_access_name()
Expand All @@ -1275,7 +1277,7 @@ impl Module for ConcatenatedModule {
}

if is_conditional {
result.add(RawSource::from_static("\n}"));
result.add(RawStringSource::from_static("\n}"));
}
}

Expand Down
Loading

2 comments on commit 2c097de

@rspack-bot
Copy link

Choose a reason for hiding this comment

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

📝 Ran ecosystem CI: Open

suite result
modernjs ✅ success
_selftest ✅ success
rsdoctor ✅ success
rspress ✅ success
rslib ✅ success
rsbuild ✅ success
examples ✅ success
devserver ✅ success
nuxt ✅ success

@rspack-bot
Copy link

Choose a reason for hiding this comment

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

📝 Benchmark detail: Open

Name Base (2024-12-05 c26a11a) Current Change
10000_big_production-mode_disable-minimize + exec 36.9 s ± 632 ms 36.5 s ± 202 ms -0.92 %
10000_development-mode + exec 1.81 s ± 44 ms 1.76 s ± 18 ms -2.48 %
10000_development-mode_hmr + exec 638 ms ± 7 ms 640 ms ± 6.1 ms +0.32 %
10000_production-mode + exec 2.34 s ± 47 ms 2.33 s ± 46 ms -0.55 %
arco-pro_development-mode + exec 1.71 s ± 63 ms 1.74 s ± 66 ms +1.77 %
arco-pro_development-mode_hmr + exec 425 ms ± 2.9 ms 424 ms ± 3.5 ms -0.12 %
arco-pro_production-mode + exec 3.12 s ± 67 ms 3.11 s ± 99 ms -0.11 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 3.18 s ± 59 ms 3.2 s ± 133 ms +0.72 %
threejs_development-mode_10x + exec 1.64 s ± 24 ms 1.61 s ± 19 ms -1.53 %
threejs_development-mode_10x_hmr + exec 806 ms ± 4.8 ms 786 ms ± 11 ms -2.48 %
threejs_production-mode_10x + exec 4.91 s ± 34 ms 4.88 s ± 23 ms -0.54 %
10000_big_production-mode_disable-minimize + rss memory 10152 MiB ± 158 MiB 10121 MiB ± 71.3 MiB -0.30 %
10000_development-mode + rss memory 805 MiB ± 78.1 MiB 782 MiB ± 46.3 MiB -2.86 %
10000_development-mode_hmr + rss memory 1871 MiB ± 197 MiB 1940 MiB ± 331 MiB +3.70 %
10000_production-mode + rss memory 664 MiB ± 33.8 MiB 672 MiB ± 29.2 MiB +1.21 %
arco-pro_development-mode + rss memory 697 MiB ± 36.4 MiB 707 MiB ± 44.5 MiB +1.43 %
arco-pro_development-mode_hmr + rss memory 890 MiB ± 56.5 MiB 940 MiB ± 41.5 MiB +5.66 %
arco-pro_production-mode + rss memory 808 MiB ± 73.2 MiB 814 MiB ± 45.5 MiB +0.83 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 819 MiB ± 30.7 MiB 825 MiB ± 33 MiB +0.69 %
threejs_development-mode_10x + rss memory 768 MiB ± 43.1 MiB 750 MiB ± 29.7 MiB -2.30 %
threejs_development-mode_10x_hmr + rss memory 1722 MiB ± 324 MiB 1725 MiB ± 211 MiB +0.17 %
threejs_production-mode_10x + rss memory 1088 MiB ± 86.1 MiB 1081 MiB ± 62.5 MiB -0.61 %

Please sign in to comment.