Skip to content

Conversation

@lor1113
Copy link
Contributor

@lor1113 lor1113 commented Dec 25, 2025

Hi,

I have found that for some use cases DocumentNode.apply_schema() can be very very slow, due to the multiple nested loops of comparisons and checks (especially the real culprit here is iter_substitutes which in my sample test run was called 463,201,585 times (for comparison, with the hotfix, it is called a somewhat more reasonable 1,490,801 times)). As a temporary hotfix patch for this I have implemented a cache in apply_schema() that caches the result of getting a matching XsdElement from a XsdGroup and returns it instead of having to run the very slow is_matching() repeatedly.

Test status of patch:

  • Github actions build+tests = passing
  • elementpath run_all_tests script (python 3.14, windows WSL2) = 24 errors, all of which related to the locale in some way (locale.Error: unsupported locale setting), unrelated to hotfix (they happen even without it)
  • elementpath run_w3c_tests script (python 3.14, windows WSL2) = all passing
  • xmlschema run_all_tests script with hotfix added on installed elementpathmodule (python 3.14, windows WSL2) = all passing
  • xmlschema run_w3c_tests script with hotfix added on installed elementpathmodule (python 3.14, windows WSL2) = all passing

I have tried multiple times to do more thorough tests with tox. Unfortunately tox does not like me and was constantly spitting out bizarre errors no matter how I tried to reconfigure or change things. So this is the best I can do for now testing wise.

Attached are some images of before and after profile runs (github does not want to let me upload the raw .prof files). For my use case, the speedup is over 100x. For other cases it might be less, or even a tiny slowdown in cases where the cache is never hit, but I would imagine that is exceedingly unlikely, and even in such a case, it should be a very negligible slowdown (compared to >100x speedup in particularly demanding cases)

No hotfix / version 5.0.4:
image

With hotfix:
image

I'm sending this as a PR because I think this might be beneficial to other users of elementpath, if for whatever reason you don't want to merge it, I will maintain it as a patch on a private copy. I am also interested in investigating other ways to speedup elementpath (as well as reduce memory footprint) that might involve more comprehensive rewrites as opposed to a quick caching patch like this, but this is a good start for now at least.

@brunato
Copy link
Member

brunato commented Dec 26, 2025

Hi @lor1113 ,
speed-up tag matching for schema object is one the key-points to improve the overall performance of xmlschema and elementpath in cascade.

The problem in general caching of iter_substitutes() have to consider many situations where the schema is not completely built or extended.

I've tested your double-level caching based on id() of the model group (including ref) and seems to pass all my tests without further errors, so i think that is safe on this local scope of apply_schema() so I'm going to merge and the include in the next version that is arriving soon (maybe this will be a minor version, for Python 3.10+). I will examine if the same approach could be useful for xmlschema in general.

Thank you for the code and analysis

Davide

@brunato brunato merged commit f3c4db3 into sissaschool:master Dec 26, 2025
19 checks passed
brunato added a commit that referenced this pull request Dec 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants