Comments (8)
Could you try schemars 0.8.16? It contains a small change that puts a temporary value in a variable instead of passing it directly as an argument to a function - when I tested it locally with your CountryCode
example, this change reduced MIR output size by ~30%
I'm sure many further improvements could be made, but it seemed worth getting a quick minimal improvement out for now
from schemars.
Thanks very much for that improvement -- now compiling kittycad takes 57 seconds down from 90 seconds, a big improvement!
If it's OK with you I'm going to keep this issue open so we can discuss further improvements -- I really appreciate the dramatic improvement so far!
from schemars.
On my real-world project (i.e. https://github.com/KittyCAD/kittycad.rs/), compile time is VASTLY improved!
0.8.19
real 36.21s
user 205.51s
sys 10.14s
maxmem 1,134,992k
0.8.17
real 68.42s
user 239.05s
sys 9.93s
maxmem 1,246,608k
Thank you so much @icewind1991 and @GREsau.
from schemars.
I'm not familiar with LLVM and so I'm not really sure why JsonSchema derive expands to such a huge amount of LLVM lines. By comparison, the serde derives output 5 orders of magnitude less LLVM lines.
it would be interesting to see the amount of generated MIR for each - the expansion you showed me had a lot of calls to ..SchemaObject::default and i wonder if it's generating a new assignment for every field in SchemaObject
you can use -Z unpretty=mir to see what the MIR is before LLVM lowering
from schemars.
@jyn514 How do I use that flag? I've tried
cargo +nightly -Z unpretty=mir build
cargo +nightly build -Z unpretty=mir
and other combinations but it always just says "unknown -Z flag specified: unpretty"
from schemars.
@adamchalmers it's a rustc flag - try something like cargo +nightly rustc -- -Z unpretty=mir
from schemars.
Thanks, here's the expansion.
The majority of MIR is made up of code like this (this pattern occurs 64744 times):
bb64701 (cleanup): {
drop(_300) -> [return: bb64702, unwind terminate(cleanup)];
}
bb64702 (cleanup): {
drop(_278) -> [return: bb64703, unwind terminate(cleanup)];
}
bb64703 (cleanup): {
drop(_256) -> [return: bb64704, unwind terminate(cleanup)];
}
This takes up the vast majority of lines.
from schemars.
I don't know if this is already well-known, but I was reading Adam's great blog post about this situation: https://blog.adamchalmers.com/crazy-compile-time/ and I'm pretty sure that the compile time here would be effectively linear if the derive macro used a loop to build the array of variants.
Currently this code:
#[derive(schemars::JsonSchema, serde::Deserialize, serde::Serialize)]
pub enum CountryCode {
#[serde(rename = "AF")]
Af,
#[serde(rename = "AX")]
Ax
}
Expands to (I'm sure that's actually a vec!
):
fn json_schema(
gen: &mut schemars::gen::SchemaGenerator,
) -> schemars::schema::Schema {
schemars::schema::Schema::Object(schemars::schema::SchemaObject {
instance_type: Some(schemars::schema::InstanceType::String.into()),
enum_values: Some(
<[_]>::into_vec(
#[rustc_box]
::alloc::boxed::Box::new(["AF".into(), "AX".into()]),
),
),
..Default::default()
})
}
But I'm suggesting that it expand to something like this:
fn json_schema(
gen: &mut schemars::gen::SchemaGenerator,
) -> schemars::schema::Schema {
schemars::schema::Schema::Object(schemars::schema::SchemaObject {
instance_type: Some(schemars::schema::InstanceType::String.into()),
enum_values: Some(
["AF", "AX"].into_iter().map(|v| v.into()).collect()
),
..Default::default()
})
}
I know that's much easier to write in surface Rust than to make happen in a macro.
from schemars.
Related Issues (20)
- Consider updating `schemars_derive` to use `syn` v2 HOT 1
- Allow #[schemars(with = "Type")] on struct HOT 1
- Support Avro schema generation?
- Example for JsonSchema without definition references HOT 1
- Maintenance status HOT 1
- enums: serde rename_all_fields not respected
- Schemars can't deal with TOML files HOT 2
- Annotate a field so it is both `required` and `default`
- schemars_derive breaks with version serde_derive_internals 0.29.0 HOT 1
- Support for humantime
- Add CI with latest dependencies
- Support `allowTrailingCommas` in schema
- Compatibility with json-schema.org ? HOT 1
- Switch to indexmap 2 for the `preserve_order` feature
- 0.8.18 regression - "type annotations needed" on variantless enum HOT 1
- skip_if for conditional skip
- Behavior change in 0.8.19 with `default`, `required`, and `skip_serializing_if` HOT 3
- `Option` no longer has a default of null as of v0.8.18 HOT 2
- Range for standard number types
- Expected schemars description attribute to be a string HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from schemars.