Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Refactor and optimize schema cleaning logic#11244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Viicos merged 10 commits intomainfromref-schema-walking
Jan 29, 2025
Merged

Conversation

Viicos
Copy link
Member

@ViicosViicos commentedJan 9, 2025
edited
Loading

Change Summary

Closes#10655,fixes#10285

This is slightly identical to#10655, with the difference that:

  • only contains the relevant changes (the rest was split off in smaller PRs)
  • Implements the schema traversing logic in Python instead of inpydantic-core. Out of 3-4s, the rust implementation takes 20ms, while the Python one takes 230ms. I don't know yet if we should keep it in Python (it has advantages: type checking, easier debugging).
  • simplifies the schema traversing logic (simplified context class, etc)
  • simplifies schema inlining logic (no need to check for recursive refs)

Concerns (1 so far):

  • Consequence of the new schema traversing logic: we don't traverse schemas that have been unpacked from another model. With the following:

    frompydanticimportBaseModelclassStandaloneModel(BaseModel): ...classM1(BaseModel):m:StandaloneModel

    The core schema of M1 is:

    M1 core schema
    {│'type':'model',│'cls':<class'__main__.M1'>,│'schema': {│   │'type':'model-fields',│   │'fields': {│   │   │'m': {│   │   │   │'type':'model-field',│   │   │   │'schema': {│   │   │   │   │'type':'model',│   │   │   │   │'cls':<class'__main__.StandaloneModel'>,│   │   │   │   │'schema': {'type':'model-fields','fields': {},'model_name':'StandaloneModel','computed_fields': []},│   │   │   │   │'config': {'title':'StandaloneModel'},│   │   │   │   │'ref':'__main__.StandaloneModel:94970984129568',│   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   },│   │   │   │'metadata': {}│   │   │   }│   │   },│   │'model_name':'M1',│   │'computed_fields': []│   },│'config': {'title':'M1'},│'ref':'__main__.M1:94970983986336',│'metadata': {'<stripped>'}}

    As you can see,Model is inlined inside the core schema for fieldm.

    Now if you do:

    classM2(BaseModel):m1:M1m:StandaloneModel

    StandaloneModel is used twice inM2 (inm andM1.m). However, the inlined core schema forM1.StandaloneModel is not transformed back into a'definition-ref' schema (and doing so would require a copy of the schema to avoid mutating the core schema ofM1 fromM2!):

    M2 core schema
    {│'type':'model',│'cls':<class'__main__.M2'>,│'schema': {│   │'type':'model-fields',│   │'fields': {│   │   │'m1': {│   │   │   │'type':'model-field',│   │   │   │'schema': {│   │   │   │   │'type':'model',│   │   │   │   │'cls':<class'__main__.M1'>,│   │   │   │   │'schema': {│   │   │   │   │   │'type':'model-fields',│   │   │   │   │   │'fields': {│   │   │   │   │   │   │'m': {│   │   │   │   │   │   │   │'type':'model-field',│   │   │   │   │   │   │   │'schema': {│   │   │   │   │   │   │   │   │'type':'model',│   │   │   │   │   │   │   │   │'cls':<class'__main__.StandaloneModel'>,│   │   │   │   │   │   │   │   │'schema': {'type':'model-fields','fields': {},'model_name':'StandaloneModel','computed_fields': []},│   │   │   │   │   │   │   │   │'config': {'title':'StandaloneModel'},│   │   │   │   │   │   │   │   │'ref':'__main__.StandaloneModel:94970985756064',│   │   │   │   │   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   │   │   │   │   },│   │   │   │   │   │   │   │'metadata': {}│   │   │   │   │   │   │   }│   │   │   │   │   │   },│   │   │   │   │   │'model_name':'M1',│   │   │   │   │   │'computed_fields': []│   │   │   │   │   },│   │   │   │   │'config': {'title':'M1'},│   │   │   │   │'ref':'__main__.M1:94970985783632',│   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   },│   │   │   │'metadata': {}│   │   │   },│   │   │'m': {│   │   │   │'type':'model-field',│   │   │   │'schema': {│   │   │   │   │'type':'model',│   │   │   │   │'cls':<class'__main__.StandaloneModel'>,│   │   │   │   │'schema': {'type':'model-fields','fields': {},'model_name':'StandaloneModel','computed_fields': []},│   │   │   │   │'config': {'title':'StandaloneModel'},│   │   │   │   │'ref':'__main__.StandaloneModel:94970985756064',│   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   },│   │   │   │'metadata': {}│   │   │   }│   │   },│   │'model_name':'M2',│   │'computed_fields': []│   },│'config': {'title':'M2'},│'ref':'__main__.M2:94970985797664',│'metadata': {'<stripped>'}}

    Onmain,StandaloneModel is properly stored in definitions, and'definition-ref' schemas are used:

    M2 core schema on main
    {│'type':'definitions',│'schema': {│   │'type':'model',│   │'cls':<class'__main__.M2'>,│   │'schema': {│   │   │'type':'model-fields',│   │   │'fields': {│   │   │   │'m1': {│   │   │   │   │'type':'model-field',│   │   │   │   │'schema': {│   │   │   │   │   │'type':'model',│   │   │   │   │   │'cls':<class'__main__.M1'>,│   │   │   │   │   │'schema': {│   │   │   │   │   │   │'type':'model-fields',│   │   │   │   │   │   │'fields': {│   │   │   │   │   │   │   │'m': {│   │   │   │   │   │   │   │   │'type':'model-field',│   │   │   │   │   │   │   │   │'schema': {'type':'definition-ref','schema_ref':'__main__.StandaloneModel:101823146688192'},│   │   │   │   │   │   │   │   │'metadata': {}│   │   │   │   │   │   │   │   }│   │   │   │   │   │   │   },│   │   │   │   │   │   │'model_name':'M1',│   │   │   │   │   │   │'computed_fields': []│   │   │   │   │   │   },│   │   │   │   │   │'config': {'title':'M1'},│   │   │   │   │   │'ref':'__main__.M1:101823149646624',│   │   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   │   },│   │   │   │   │'metadata': {}│   │   │   │   },│   │   │   │'m': {│   │   │   │   │'type':'model-field',│   │   │   │   │'schema': {'type':'definition-ref','schema_ref':'__main__.StandaloneModel:101823146688192'},│   │   │   │   │'metadata': {}│   │   │   │   }│   │   │   },│   │   │'model_name':'M2',│   │   │'computed_fields': []│   │   },│   │'config': {'title':'M2'},│   │'ref':'__main__.M2:101823148327728',│   │'metadata': {'<stripped>'}│   },│'definitions': [│   │   {│   │   │'type':'model',│   │   │'cls':<class'__main__.StandaloneModel'>,│   │   │'schema': {'type':'model-fields','fields': {},'model_name':'StandaloneModel','computed_fields': []},│   │   │'config': {'title':'StandaloneModel'},│   │   │'ref':'__main__.StandaloneModel:101823146688192',│   │   │'metadata': {'<stripped>'}│   │   }│   ]}

    Both approaches are valid, but it might be that this cause unexpected issues (JSON Schema differences, etc). Regarding memory consumption, it is slightly affected. Taking thek8s_v2.py file as an example (it is a good one because the "issue" described here happens several times in it), we don't see any increase/decrease in %RAM consumption, although profile over time differs:

    PRmain
    imageimage

@github-actionsgithub-actionsbot added the relnotes-fixUsed for bugfixes. labelJan 9, 2025
@cloudflare-workers-and-pagesCloudflare Workers and Pages
Copy link

cloudflare-workers-and-pagesbot commentedJan 9, 2025
edited
Loading

Deploying pydantic-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit:76b7109
Status: ✅  Deploy successful!
Preview URL:https://2c6bd658.pydantic-docs.pages.dev
Branch Preview URL:https://ref-schema-walking.pydantic-docs.pages.dev

View logs

@codspeed-hqCodSpeed HQ
Copy link

codspeed-hqbot commentedJan 9, 2025
edited
Loading

CodSpeed Performance Report

Merging#11244 willimprove performances by 33.86%

Comparingref-schema-walking (76b7109) withmain (4722283)

Summary

⚡ 19 improvements
✅ 26 untouched benchmarks

Benchmarks breakdown

BenchmarkBASEHEADChange
test_schema_build2.9 ms2.5 ms+15.75%
test_fastapi_startup_perf200.5 ms149.8 ms+33.86%
test_fastapi_startup_perf26.2 ms21.1 ms+24.27%
test_complex_model_schema_generation1.8 ms1.5 ms+22.43%
test_construct_dataclass_schema1.8 ms1.4 ms+32.26%
test_lots_of_models_with_lots_of_fields2.7 s2.3 s+13.66%
test_model_validators_serializers906.4 µs758.1 µs+19.56%
test_nested_model_schema_generation1,136.4 µs869.8 µs+30.65%
test_recursive_model_schema_generation1,016.4 µs850.5 µs+19.51%
test_simple_model_schema_generation746.3 µs618.7 µs+20.63%
test_simple_model_schema_lots_of_fields_generation28.5 ms22.7 ms+25.5%
test_tagged_union_with_callable_discriminator_schema_generation1.5 ms1.1 ms+31.54%
test_tagged_union_with_str_discriminator_schema_generation1.5 ms1.2 ms+32.62%
test_deeply_nested_recursive_model_schema_generation1.3 ms1.1 ms+21.63%
test_generic_recursive_model_schema_generation894.3 µs740.1 µs+20.83%
test_nested_recursive_generic_model_schema_generation1.7 ms1.4 ms+21.57%
test_nested_recursive_model_schema_generation1.8 ms1.5 ms+19.97%
test_recursive_discriminated_union_with_base_model1.7 ms1.4 ms+18.88%
test_simple_recursive_model_schema_generation774.5 µs624.6 µs+23.99%

@ViicosViicos added the third-party-testsAdd this label on a PR to trigger 3rd party tests labelJan 9, 2025
@ViicosViicos closed thisJan 9, 2025
@ViicosViicos reopened thisJan 9, 2025
@rmorshearmorshea mentioned this pull requestJan 13, 2025
13 tasks
@ViicosViicos marked this pull request as ready for reviewJanuary 21, 2025 20:11
@ViicosViicosforce-pushed theref-schema-walking branch 2 times, most recently from48dc1a7 to818269dCompareJanuary 21, 2025 20:30
@sydney-runkle
Copy link
Contributor

I think we can mark this as closing#10655

Viicos reacted with thumbs up emoji

@sydney-runkle
Copy link
Contributor

To be deleted:
apply_discriminators
Walk logic in _core_utils

As in, in a new commit on this PR, you're just refraining for now?

Viicos reacted with thumbs up emoji

@sydney-runkle
Copy link
Contributor

Consequence of the new schema traversing logic: we don't traverse schemas that have been unpacked from another model.

A few questions:

  1. Is theM1 schema different onmain?
  2. I don't think this is a huge issue for small cases like this, but imagine you had 10 refs toStandaloneModel orM1, then schemas would start to get quite verbose. So, two spinoff questions here - a) does this affect JSON schema gen? b) should we be concerned about increased storage cost for non-optimized validators/serializers built from these schemas?

I think it would be really good to loop in@adriangb here - he worked a lot with refs/defs in core schema gen, or so the blame says 😉.

@sydney-runkle
Copy link
Contributor

sydney-runkle commentedJan 22, 2025
edited
Loading

Alright, a few things before I dive into an in depth review:

  • I think the performance gains here might be worth the slightly less optimized / brief schema gen, but maybe we could find a happy medium by adding one more refs / defs collection pass - I understand we want to avoid an abundance of redundancy with cleaning though. One idea is that we could keep sort of key/value store indicating references to a certain type + do a replacement pass if a threshold (maybe 2) is passed.
  • Looks like tests are failing (also 3.9 tests bc we can't use a match statement)
  • I think one important thing for reviewers here to realize is that we attempted to move this cleaning logic to rust to speed things up, but having the logic in Python isn't much slower, and is much easier to maintain.@Viicos, could you add a note like this to the description + potentially some benchmarks if you have them on hand?

Copy link
Contributor

@sydney-runklesydney-runkle left a comment

Choose a reason for hiding this comment

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

Generally, seems promising. I've already voiced some concerns in independent comments that we can chat about.

I think it'd be helpful to see the deletion of those other methods for comparison purposes on this PR 👍

Comment on lines -390 to +391
'$defs': {'MySeq_int_': {'items': {'type': 'integer'}, 'type': 'array'}},
'properties': {'my_int_seq': {'$ref': '#/$defs/MySeq_int_'}},
'$defs': {'MyIntSeq': {'items': {'type': 'integer'}, 'type': 'array'}},
'properties': {'my_int_seq': {'$ref': '#/$defs/MyIntSeq'}},
Copy link
Contributor

Choose a reason for hiding this comment

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

A note about this change, discussed in detail previously:#10655 (comment)

@Viicos
Copy link
MemberAuthor

  1. Is theM1 schema different onmain?

It it the same

2. I don't think this is a huge issue for small cases like this, but imagine you had 10 refs toStandaloneModel orM1, then schemas would start to get quite verbose. So, two spinoff questions here - a) does this affect JSON schema gen? b) should we be concerned about increased storage cost for non-optimized validators/serializers built from these schemas?

If you have more that 1 reference toStandaloneModel, then you will end up with a'definitions' schema, that will be unpacked when buildingM2 anyway. So mostly this is only an issue when something is referenced once (so that the reference is inlined) and then you reuse the whole schema (in this case, schema ofM1) somewhere else.

a) It does affect JSON Schema gen
b) I don't think it will. Actually, I'm going to check how memory behaves here. Onmain, we currently copy the whole schema once (even the unpacked ones), which isn't the case here.

Looks like tests are failing (also 3.9 tests bc we can't use a match statement)

Only failing tests are because of the match statement that I need to change.

could you add a note like this to the description + potentially some benchmarks if you have them on hand?

yes sorry the PR description isn't complete yet.

sydney-runkle reacted with heart emoji

@adriangb
Copy link
Member

Consequence of the new schema traversing logic: we don't traverse schemas that have been unpacked from another model.

A few questions:

  1. Is theM1 schema different onmain?
  2. I don't think this is a huge issue for small cases like this, but imagine you had 10 refs toStandaloneModel orM1, then schemas would start to get quite verbose. So, two spinoff questions here - a) does this affect JSON schema gen? b) should we be concerned about increased storage cost for non-optimized validators/serializers built from these schemas?

I think it would be really good to loop in@adriangb here - he worked a lot with refs/defs in core schema gen, or so the blame says 😉.

The issue is not just verbose schemas but also duplicate SchemaValidator's.
ImagineStandaloneModel ishuge. We'd now be creatingmultiple (possibly hundreds, unbounded) copies of it'sSchemaValidator instead of just 1.

@Viicos
Copy link
MemberAuthor

The issue is not just verbose schemas but also duplicate SchemaValidator's.
ImagineStandaloneModel ishuge. We'd now be creatingmultiple (possibly hundreds, unbounded) copies of it'sSchemaValidator instead of just 1.

I'll note that this is only an issue with the following setup:

classStandaloneModel(BaseModel): ...classM1(BaseModel):m:StandaloneModel# If StandaloneModel is referenced another time,# M1's core schema is transformed in a `'definitions'` schema,# and we don't have any duplication of StandaloneModel's cs.classM2(BaseModel):m:StandaloneModel# Same note as M1...classOuter(BaseModel):m:StandaloneModel# Same note as M1 and M2m1:M1# If M1 is referenced another time,# Outer's core schema is transformed in a `'definitions'` schema,# and we don't have any duplication of M1's csm2:M2# Same    ...mx:MX

Which is relatively uncommon. Boxy's work will help here as well in reusing validator instances. JSON Schema changes is still an issue though (still valid, but the structure changes and this generally create churn in user code), so I'm looking into a way to have the previous behavior).

sydney-runkle and fruitoiz reacted with thumbs up emoji

@ViicosViicosforce-pushed theref-schema-walking branch 2 times, most recently fromb258a3e tofe0db49CompareJanuary 22, 2025 17:08
@sydney-runkle
Copy link
Contributor

Thanks for the clarification@Viicos. I'm less concerned now about this defs/refs simplification now that I understand it's semi-limited.

That being said, I do think think we might want to revisit an extra pass here in the future if/when we can get significant memory usage improvements with Boxy's work (cc@davidhewitt).

Happy to take another pass over this - could you remove the existing walk / discriminator logic so I can compare?

Thanks for all of your work here and the detailed explanations of some complex patterns.

@ViicosViicosforce-pushed theref-schema-walking branch 2 times, most recently fromdbced49 to0321015CompareJanuary 24, 2025 16:14
@github-actionsGitHub Actions
Copy link
Contributor

github-actionsbot commentedJan 24, 2025
edited
Loading

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  pydantic
  type_adapter.py298
  pydantic/_internal
  _core_utils.py113,119-145,166-178
  _dataclasses.py174
  _generate_schema.py2511
  _model_construction.py
  _schema_gather.py101-103
Project Total 

This report was generated bypython-coverage-comment-action

return schema


def _can_be_inlined(def_ref: core_schema.DefinitionReferenceSchema) -> bool:
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Difference from MS PR: instead of checking for specific keys in the metadata schema, we just check that there are no metadata at all.

sydney-runkle reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we inline if there's metadata, ex json schema related metadata?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

fromtypingimportAnnotatedfrompydanticimportBaseModel,WithJsonSchematypeTest=intclassModel(BaseModel):f:Annotated[Test,WithJsonSchema({})]Model.__pydantic_core_schema__{│'type':'definitions',│'schema': {│   │'type':'model',│   │'cls':<class'__main__.Model'>,│   │'schema': {│   │   │'type':'model-fields',│   │   │'fields': {│   │   │   │'t1': {'type':'model-field','schema': {'type':'int'},'metadata': {}},│   │   │   │'t2': {│   │   │   │   │'type':'model-field',│   │   │   │   │'schema': {'type':'definition-ref','schema_ref':'__main__.Test:124259184101792','metadata': {'<stripped>'}},│   │   │   │   │'metadata': {}│   │   │   │   }│   │   │   },│   │   │'model_name':'Model',│   │   │'computed_fields': []│   │   },│   │'config': {'title':'Model'},│   │'ref':'__main__.Model:107106664271472',│   │'metadata': {'<stripped>'}│   },│'definitions': [{'type':'int','ref':'__main__.Test:124259184101792'}]}

If you inline the definition ref, you loose the JSON Schema metadata. It could still be inlined and the metadata moved to the referenced schema, but you'll need to make a copy of it and merge metadata somehow.

sydney-runkle reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a note about this to the code?



@pytest.mark.parametrize('deep_ref', [False,True])
@pytest.mark.xfail(
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Difference from MS PR due to the type refs changes (specifically the GPCS method change). The generated schemas are still valid, but in this case the output is different:

On this branch, the core schema for M1 is:

{│'type':'definitions',│'schema': {│   │'type':'model',│   │'cls':<class'__main__.M1'>,│   │'schema': {│   │   │'type':'model-fields',│   │   │'fields': {'a': {'type':'model-field','schema': {'type':'definition-ref','schema_ref':'__main__.M2:101691608428272'},'metadata': {}}},│   │   │'model_name':'M1',│   │   │'computed_fields': []│   │   },│   │'config': {'title':'M1'},│   │'ref':'__main__.M1:101691610240000',│   │'metadata': {'<stripped>'}│   },│'definitions': [│   │   {│   │   │'type':'model',│   │   │'cls':<class'__main__.M2'>,│   │   │'schema': {│   │   │   │'type':'model-fields',│   │   │   │'fields': {│   │   │   │   │'b': {│   │   │   │   │   │'type':'model-field',│   │   │   │   │   │'schema': {│   │   │   │   │   │   │'type':'model',│   │   │   │   │   │   │'cls':<class'__main__.M1'>,│   │   │   │   │   │   │'schema': {│   │   │   │   │   │   │   │'type':'model-fields',│   │   │   │   │   │   │   │'fields': {│   │   │   │   │   │   │   │   │'a': {│   │   │   │   │   │   │   │   │   │'type':'model-field',│   │   │   │   │   │   │   │   │   │'schema': {'type':'definition-ref','schema_ref':'__main__.M2:101691608428272'},│   │   │   │   │   │   │   │   │   │'metadata': {}│   │   │   │   │   │   │   │   │   }│   │   │   │   │   │   │   │   },│   │   │   │   │   │   │   │'model_name':'M1',│   │   │   │   │   │   │   │'computed_fields': []│   │   │   │   │   │   │   },│   │   │   │   │   │   │'config': {'title':'M1'},│   │   │   │   │   │   │'ref':'__main__.M1:101691610240000',│   │   │   │   │   │   │'metadata': {'<stripped>'}│   │   │   │   │   │   },│   │   │   │   │   │'metadata': {}│   │   │   │   │   }│   │   │   │   },│   │   │   │'model_name':'M2',│   │   │   │'computed_fields': []│   │   │   },│   │   │'config': {'title':'M2'},│   │   │'ref':'__main__.M2:101691608428272',│   │   │'metadata': {'<stripped>'}│   │   }│   ]}

As we can see, the core schema forM1 appears twice and could be inlined.

sydney-runkle reacted with thumbs up emoji
@ViicosViicosforce-pushed theref-schema-walking branch 2 times, most recently fromc1fffce toe093879CompareJanuary 27, 2025 18:44
Copy link
Contributor

@sydney-runklesydney-runkle left a comment

Choose a reason for hiding this comment

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

In general, I feel like_generate_schema.py could use a lot more documentation, given that schema gen + ref/def simplification is complicated by nature.

This constitutes a really significant improvement though, great work.

I like the new typed nature of the schema gathering results, etc. Easier to follow that logic as well! I'd like to take one more pass over_schema_gather.py, but generally, really happy with this improvement.

return schema


def _can_be_inlined(def_ref: core_schema.DefinitionReferenceSchema) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we inline if there's metadata, ex json schema related metadata?

@ViicosViicosforce-pushed theref-schema-walking branch 2 times, most recently fromd74190f to7340799CompareJanuary 28, 2025 12:59
Copy link
Contributor

@sydney-runklesydney-runkle left a comment

Choose a reason for hiding this comment

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

Looking really good. Happy to approve pending consideration of my final nit picks :)

Copy link
Contributor

@sydney-runklesydney-runkle left a comment

Choose a reason for hiding this comment

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

Great work@Viicos, perf wins like this take a lot of deep thought and work.

@MarkusSintonen, thanks for the ideas and blueprint here! We're really excited about this perf boost.

@ViicosViicos merged commit8fe3aae intomainJan 29, 2025
78 checks passed
@ViicosViicos deleted the ref-schema-walking branchJanuary 29, 2025 17:55
@ViicosViicos added relnotes-performanceUsed for performance improvements. and removed relnotes-fixUsed for bugfixes. labelsJan 29, 2025
@MarkusSintonen
Copy link
Contributor

MarkusSintonen commentedJan 30, 2025
edited
Loading

Thanks@sydney-runkle /@Viicos!

Why the generictest_fastapi_startup_perf case shows much lower level of improvement? This one has "only"+33.86% but the previous PR had×2.2?

Generic models construction is the most painful issue as that has been so slow.

@Viicos
Copy link
MemberAuthor

Why the generictest_fastapi_startup_perf case shows much lower level of improvement? This one has "only"+33.86% but the previous PR had×2.2?

It's not entirely clear to me why this benchmark had better results than the other ones. I compared both flamegraphs on this benchmark, on this PR and yours, and couldn't find any significant time difference being spent in schema gathering (as that's the only significant difference between the two PRs -- this one is implemented in Python and so is a bit slower, however this isn't significant).

Note that since then, we merged other performance improvements so the percentages aren't really comparable.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@sydney-runklesydney-runklesydney-runkle approved these changes

Assignees
No one assigned
Labels
relnotes-performanceUsed for performance improvements.third-party-testsAdd this label on a PR to trigger 3rd party tests
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Performance issues related to schema cleaning
4 participants
@Viicos@sydney-runkle@adriangb@MarkusSintonen

[8]ページ先頭

©2009-2025 Movatter.jp