Repository: tefra/xsdata
Pull request #497 (2021-05-23 11:44:50)

Performance tweaks
Goal find another 5-10% performance tweaks for the netex benchmark suite

 - [x] Convert XmlMeta  namespace from property to attribute
 - [x] Use __slots__ for XmlNode(s)
 - [x] Speedup XmlDuration initialization
 - [x] Speedup ElementNode.bind process
 - [x] Speedup ElementNode.child process
 - [x] Decrease string cloning

Netext Benchmark reference: So far **-9.8%**
**Before:** 36.122270822525024
**After:** 32.574384927749634


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)


codecov[bot]: # [Codecov](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) Report
> Merging [#497](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (a250d57) into [master](https://codecov.io/gh/tefra/xsdata/commit/038896f5f3917204d1ac671940a03a4466d4a1b2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (038896f) will **decrease** coverage by `0.06%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/tefra/xsdata/pull/497/graphs/tree.svg?width=650&height=150&src=pr&token=YzDDLtywvl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)

```diff
@@             Coverage Diff             @@
##            master     #497      +/-   ##
===========================================
- Coverage   100.00%   99.93%   -0.07%     
===========================================
  Files           84       85       +1     
  Lines         7436     7445       +9     
  Branches      1339     1330       -9     
===========================================
+ Hits          7436     7440       +4     
- Misses           0        3       +3     
- Partials         0        2       +2     
```


| [Impacted Files](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) | Coverage Δ | |
|---|---|---|
| [xsdata/formats/dataclass/models/elements.py](https://codecov.io/gh/tefra/xsdata/pull/497/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL21vZGVscy9lbGVtZW50cy5weQ==) | `98.88% <100.00%> (-1.12%)` | :arrow_down: |
| [xsdata/formats/dataclass/parsers/mixins.py](https://codecov.io/gh/tefra/xsdata/pull/497/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL3BhcnNlcnMvbWl4aW5zLnB5) | `100.00% <100.00%> (ø)` | |
| [xsdata/formats/dataclass/parsers/nodes.py](https://codecov.io/gh/tefra/xsdata/pull/497/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL3BhcnNlcnMvbm9kZXMucHk=) | `100.00% <100.00%> (ø)` | |
| [xsdata/utils/mixins.py](https://codecov.io/gh/tefra/xsdata/pull/497/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL3V0aWxzL21peGlucy5weQ==) | `100.00% <100.00%> (ø)` | |
| [xsdata/formats/dataclass/typing.py](https://codecov.io/gh/tefra/xsdata/pull/497/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2Zvcm1hdHMvZGF0YWNsYXNzL3R5cGluZy5weQ==) | `97.02% <0.00%> (-2.98%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). Last update [038896f...a250d57](https://codecov.io/gh/tefra/xsdata/pull/497?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='1.1%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [1.1% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='1.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [1.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='1.3%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [1.3% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=VULNERABILITY)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=497&resolved=false&types=SECURITY_HOTSPOT)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=497&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo.png' alt='No Coverage information' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497) No Coverage information  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='1.3%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list) [1.3% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=497&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c80b956a..363e70cb 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,4 +1,4 @@
-exclude: tests/fixtures|docs/examples
+exclude: tests/fixtures
 
 repos:
   - repo: https://github.com/asottile/pyupgrade
diff --git a/docs/examples/compound-fields.rst b/docs/examples/compound-fields.rst
index f0537965..e7384992 100644
--- a/docs/examples/compound-fields.rst
+++ b/docs/examples/compound-fields.rst
@@ -38,4 +38,4 @@ All choice elements are grouped into a single list field.
 
 .. testoutput::
 
-    [Alpha(a=True), Alpha(a=True), Bravo(b=True), Bravo(b=True), Alpha(a=True), Bravo(b=True), Alpha(a=True), Bravo(b=True)]
\ No newline at end of file
+    [Alpha(a=True), Alpha(a=True), Bravo(b=True), Bravo(b=True), Alpha(a=True), Bravo(b=True), Alpha(a=True), Bravo(b=True)]
diff --git a/setup.cfg b/setup.cfg
index ed2e3121..8e8a2e0a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -80,7 +80,7 @@ ignore = W503,ANN101,ANN102,E203
 max-line-length = 88
 
 [tool:pytest]
-addopts = --color=yes --benchmark-skip --benchmark-columns=min,max,mean,median
+addopts = --color=yes --benchmark-skip
 
 [coverage:run]
 omit =
diff --git a/tox.ini b/tox.ini
index db1d1459..81f9a63f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,7 +7,9 @@ extras = test,cli,soap,lxml
 commands = pytest {posargs}
 
 [testenv:benchmarks]
-commands = pytest --benchmark-only tests/integration/benchmarks
+commands =
+    pytest --benchmark-only --benchmark-columns=min,max,mean,median \
+    tests/integration/benchmarks
 
 [testenv:docs]
 basepython = python3.7
diff --git a/xsdata/formats/converter.py b/xsdata/formats/converter.py
index 3bd7baf0..a8c130f4 100644
--- a/xsdata/formats/converter.py
+++ b/xsdata/formats/converter.py
@@ -3,9 +3,6 @@ import base64
 import binascii
 import math
 import warnings
-from abc import ABCMeta
-from dataclasses import dataclass
-from dataclasses import field
 from datetime import date
 from datetime import datetime
 from datetime import time
@@ -38,7 +35,7 @@ from xsdata.utils import namespaces
 from xsdata.utils import text
 
 
-class Converter(metaclass=abc.ABCMeta):
+class Converter(abc.ABC):
     """Abstract converter class."""
 
     @abc.abstractmethod
@@ -61,13 +58,11 @@ class Converter(metaclass=abc.ABCMeta):
             )
 
 
-@dataclass
 class ConverterFactory:
-    """
-    :param registry: Converters registry
-    """
+    __slots__ = ("registry",)
 
-    registry: Dict[Type, Converter] = field(default_factory=dict)
+    def __init__(self):
+        self.registry: Dict[Type, Converter] = {}
 
     def deserialize(self, value: Any, types: Sequence[Type], **kwargs: Any) -> Any:
         """
@@ -218,6 +213,14 @@ __EXPLICIT_TYPES__ = (
 )
 
 
+class StringConverter(Converter):
+    def deserialize(self, value: Any, **kwargs: Any) -> Any:
+        return value if isinstance(value, str) else str(value)
+
+    def serialize(self, value: Any, **kwargs: Any) -> str:
+        return value if isinstance(value, str) else str(value)
+
+
 class BoolConverter(Converter):
     def deserialize(self, value: Any, **kwargs: Any) -> bool:
         if isinstance(value, str):
@@ -388,9 +391,6 @@ class QNameConverter(Converter):
         return uri, name
 
 
-Array = Union[List, Tuple]
-
-
 class EnumConverter(Converter):
     def serialize(self, value: Enum, **kwargs: Any) -> str:
         return converter.serialize(value.value, **kwargs)
@@ -418,7 +418,7 @@ class EnumConverter(Converter):
 
     @classmethod
     def match(
-        cls, value: Any, values: Array, length: int, real: Any, **kwargs: Any
+        cls, value: Any, values: Sequence, length: int, real: Any, **kwargs: Any
     ) -> bool:
 
         if isinstance(value, str) and isinstance(real, str):
@@ -433,7 +433,7 @@ class EnumConverter(Converter):
         return False
 
     @classmethod
-    def match_list(cls, raw: Array, real: Array, **kwargs: Any) -> bool:
+    def match_list(cls, raw: Sequence, real: Sequence, **kwargs: Any) -> bool:
         for index, val in enumerate(real):
             if not cls.match_atomic(raw[index], val, **kwargs):
                 return False
@@ -452,7 +452,7 @@ class EnumConverter(Converter):
         return cmp == real
 
 
-class DateTimeBase(Converter, metaclass=ABCMeta):
+class DateTimeBase(Converter, metaclass=abc.ABCMeta):
     @classmethod
     def parse(cls, value: Any, **kwargs: Any) -> datetime:
         try:
@@ -486,17 +486,19 @@ class DateTimeConverter(DateTimeBase):
         return self.parse(value, **kwargs)
 
 
-@dataclass
 class ProxyConverter(Converter):
-    """
-    :param func: the callable to convert from string
-    """
 
-    func: Callable
+    __slots__ = ("factory",)
+
+    def __init__(self, factory: Callable):
+        """
+        :param factory: factory function used to parse string values
+        """
+        self.factory = factory
 
     def deserialize(self, value: Any, **kwargs: Any) -> Any:
         try:
-            return self.func(value)
+            return self.factory(value)
         except ValueError as e:
             raise ConverterError(e)
 
@@ -505,12 +507,12 @@ class ProxyConverter(Converter):
 
 
 converter = ConverterFactory()
-converter.register_converter(str, ProxyConverter(str))
+converter.register_converter(str, StringConverter())
 converter.register_converter(int, IntConverter())
 converter.register_converter(bool, BoolConverter())
 converter.register_converter(float, FloatConverter())
 converter.register_converter(bytes, BytesConverter())
-converter.register_converter(object, ProxyConverter(str))
+converter.register_converter(object, converter.type_converter(str))
 converter.register_converter(time, TimeConverter())
 converter.register_converter(date, DateConverter())
 converter.register_converter(datetime, DateTimeConverter())
diff --git a/xsdata/formats/dataclass/models/builders.py b/xsdata/formats/dataclass/models/builders.py
index 5ca4acdb..6ba26b62 100644
--- a/xsdata/formats/dataclass/models/builders.py
+++ b/xsdata/formats/dataclass/models/builders.py
@@ -225,7 +225,7 @@ class XmlVarBuilder:
                 wildcards.append(choice)
 
         var = XmlVar(
-            index=index,
+            index=index + 1,
             name=name,
             qname=qname,
             init=init,
diff --git a/xsdata/formats/dataclass/models/elements.py b/xsdata/formats/dataclass/models/elements.py
index 82afc66f..df8d0fa6 100644
--- a/xsdata/formats/dataclass/models/elements.py
+++ b/xsdata/formats/dataclass/models/elements.py
@@ -1,4 +1,5 @@
 import operator
+import sys
 from dataclasses import is_dataclass
 from typing import Any
 from typing import Dict
@@ -8,14 +9,13 @@ from typing import Mapping
 from typing import Optional
 from typing import Sequence
 from typing import Set
+from typing import Tuple
 from typing import Type
 
 from xsdata.formats.converter import converter
 from xsdata.models.enums import NamespaceType
 from xsdata.utils import collections
-from xsdata.utils.constants import EMPTY_SEQUENCE
 from xsdata.utils.namespaces import local_name
-from xsdata.utils.namespaces import split_qname
 from xsdata.utils.namespaces import target_uri
 
 NoneType = type(None)
@@ -24,41 +24,39 @@ NoneType = type(None)
 class XmlType:
     """Xml node types."""
 
-    TEXT = "Text"
-    ELEMENT = "Element"
-    ELEMENTS = "Elements"
-    WILDCARD = "Wildcard"
-    ATTRIBUTE = "Attribute"
-    ATTRIBUTES = "Attributes"
-
-    @classmethod
-    def all(cls):
-        yield XmlType.TEXT
-        yield XmlType.ELEMENT
-        yield XmlType.ELEMENTS
-        yield XmlType.WILDCARD
-        yield XmlType.ATTRIBUTE
-        yield XmlType.ATTRIBUTES
+    TEXT = sys.intern("Text")
+    ELEMENT = sys.intern("Element")
+    ELEMENTS = sys.intern("Elements")
+    WILDCARD = sys.intern("Wildcard")
+    ATTRIBUTE = sys.intern("Attribute")
+    ATTRIBUTES = sys.intern("Attributes")
 
 
 class MetaMixin:
-    def __eq__(self, other: Any) -> bool:
-        if isinstance(other, self.__class__):
-            return tuple(self) == tuple(other)
+    """Use this mixin for unit tests only!!!"""
 
-        return NotImplemented
+    __slots__: Tuple[str, ...] = ()
+
+    def __eq__(self, other: Any) -> bool:
+        return tuple(self) == tuple(other)
 
     def __iter__(self) -> Iterator:
-        for field_name in self.__slots__:
-            yield getattr(self, field_name)
+        for name in self.__slots__:
+            yield getattr(self, name)
+
+    def __repr__(self) -> str:
+        params = (f"{name}={getattr(self, name)!r}" for name in self.__slots__)
+        return f"{self.__class__.__qualname__}({', '.join(params)})"
 
 
 class XmlVar(MetaMixin):
     """Class field binding metadata."""
 
     __slots__ = (
+        "index",
         "name",
         "qname",
+        "types",
         "init",
         "mixed",
         "tokens",
@@ -69,17 +67,17 @@ class XmlVar(MetaMixin):
         "sequential",
         "list_element",
         "default",
+        "xml_type",
+        "namespaces",
+        "elements",
+        "wildcards",
+        # Calculated
         "is_text",
         "is_element",
         "is_elements",
         "is_wildcard",
         "is_attribute",
         "is_attributes",
-        "index",
-        "types",
-        "namespaces",
-        "elements",
-        "wildcards",
         "namespace_matches",
         "clazz",
         "is_clazz_union",
@@ -88,7 +86,6 @@ class XmlVar(MetaMixin):
 
     def __init__(
         self,
-        *args: Any,
         index: int,
         name: str,
         qname: str,
@@ -107,6 +104,7 @@ class XmlVar(MetaMixin):
         namespaces: Sequence[str],
         elements: Mapping[str, "XmlVar"],
         wildcards: Sequence["XmlVar"],
+        **kwargs: Any,
     ):
         """
         :param index: Field ordering
@@ -152,6 +150,7 @@ class XmlVar(MetaMixin):
         self.clazz = collections.first(tp for tp in types if is_dataclass(tp))
         self.is_clazz_union = self.clazz and len(types) > 1
         self.local_name = local_name(qname)
+        self.xml_type = xml_type
 
         self.is_text = False
         self.is_element = False
@@ -177,24 +176,6 @@ class XmlVar(MetaMixin):
     def element_types(self) -> Set[Type]:
         return {tp for element in self.elements.values() for tp in element.types}
 
-    def get_xml_type(self) -> str:
-        if self.is_wildcard:
-            return XmlType.WILDCARD
-
-        if self.is_attribute:
-            return XmlType.ATTRIBUTE
-
-        if self.is_attributes:
-            return XmlType.ATTRIBUTES
-
-        if self.is_element:
-            return XmlType.ELEMENT
-
-        if self.is_elements:
-            return XmlType.ELEMENTS
-
-        return XmlType.TEXT
-
     def find_choice(self, qname: str) -> Optional["XmlVar"]:
         """Match and return a choice field by its qualified name."""
         match = self.elements.get(qname)
@@ -261,9 +242,6 @@ class XmlVar(MetaMixin):
         return matches
 
     def _match_namespace(self, qname: str) -> bool:
-        if qname == "*":
-            return True
-
         uri = target_uri(qname)
         if not self.namespaces and uri is None:
             return True
@@ -279,29 +257,6 @@ class XmlVar(MetaMixin):
 
         return False
 
-    def __repr__(self) -> str:
-        params = (
-            f"index={self.index}, "
-            f"name={self.name}, "
-            f"qname={self.qname}, "
-            f"types={self.types}, "
-            f"init={self.init}, "
-            f"mixed={self.mixed}, "
-            f"tokens={self.tokens}, "
-            f"format={self.format}, "
-            f"derived={self.derived}, "
-            f"any_type={self.any_type}, "
-            f"nillable={self.nillable}, "
-            f"sequential={self.sequential}, "
-            f"list_element={self.list_element}, "
-            f"default={self.default}, "
-            f"xml_type={self.get_xml_type()}, "
-            f"namespaces={self.namespaces}, "
-            f"elements={self.elements}, "
-            f"wildcards={self.wildcards}"
-        )
-        return f"{self.__class__.__name__}({params})"
-
 
 get_index = operator.attrgetter("index")
 
@@ -320,12 +275,13 @@ class XmlMeta(MetaMixin):
         "wildcards",
         "attributes",
         "any_attributes",
+        # Calculated
+        "namespace",
         "mixed_content",
     )
 
     def __init__(
         self,
-        *args: Any,
         clazz: Type,
         qname: str,
         source_qname: str,
@@ -336,6 +292,7 @@ class XmlMeta(MetaMixin):
         wildcards: Sequence[XmlVar],
         attributes: Mapping[str, XmlVar],
         any_attributes: Sequence[XmlVar],
+        **kwargs: Any,
     ):
 
         """
@@ -354,6 +311,7 @@ class XmlMeta(MetaMixin):
 
         self.clazz = clazz
         self.qname = qname
+        self.namespace = target_uri(qname)
         self.source_qname = source_qname
         self.nillable = nillable
         self.text = text
@@ -364,6 +322,15 @@ class XmlMeta(MetaMixin):
         self.any_attributes = any_attributes
         self.mixed_content = any(wildcard.mixed for wildcard in self.wildcards)
 
+    @property
+    def element_types(self) -> Set[Type]:
+        return {
+            tp
+            for elements in self.elements.values()
+            for element in elements
+            for tp in element.types
+        }
+
     def get_element_vars(self) -> List[XmlVar]:
         result = list(
             collections.concat(self.wildcards, self.choices, *self.elements.values())
@@ -392,66 +359,35 @@ class XmlMeta(MetaMixin):
 
         return sorted(result, key=get_index)
 
-    @property
-    def namespace(self) -> Optional[str]:
-        return split_qname(self.qname)[0]
-
     def find_attribute(self, qname: str) -> Optional[XmlVar]:
         return self.attributes.get(qname)
 
-    def find_elements(self, qname: str) -> Sequence[XmlVar]:
-        return self.elements.get(qname, EMPTY_SEQUENCE)
-
-    def find_choice(self, qname: str) -> Optional[XmlVar]:
-        for choice in self.choices:
-            match = choice.find_choice(qname)
-            if match:
-                return match
-
-        return None
-
     def find_any_attributes(self, qname: str) -> Optional[XmlVar]:
         return find_by_namespace(self.any_attributes, qname)
 
     def find_wildcard(self, qname: str) -> Optional[XmlVar]:
         return find_by_namespace(self.wildcards, qname)
 
-    def find_children(self, qname: str) -> Iterator[XmlVar]:
+    def find_any_wildcard(self) -> Optional[XmlVar]:
+        if self.wildcards:
+            return self.wildcards[0]
 
-        yield from self.find_elements(qname)
+        return None
 
-        chd = self.find_choice(qname)
-        if chd:
-            yield chd
+    def find_children(self, qname: str) -> Iterator[XmlVar]:
+        elements = self.elements.get(qname)
+        if elements:
+            yield from elements
+
+        for choice in self.choices:
+            match = choice.find_choice(qname)
+            if match:
+                yield match
 
         chd = self.find_wildcard(qname)
         if chd:
             yield chd
 
-    @property
-    def element_types(self) -> Set[Type]:
-        return {
-            tp
-            for elements in self.elements.values()
-            for element in elements
-            for tp in element.types
-        }
-
-    def __repr__(self) -> str:
-        params = (
-            f"clazz={self.clazz}, "
-            f"qname={self.qname}, "
-            f"source_qname={self.source_qname}, "
-            f"nillable={self.nillable}, "
-            f"text={self.text}, "
-            f"choices={self.choices}, "
-            f"elements={self.elements}, "
-            f"wildcards={self.wildcards}, "
-            f"attributes={self.attributes}, "
-            f"any_attributes={self.any_attributes}"
-        )
-        return f"{self.__class__.__name__}({params})"
-
 
 def find_by_namespace(xml_vars: Sequence[XmlVar], qname: str) -> Optional[XmlVar]:
     for xml_var in xml_vars:
diff --git a/xsdata/formats/dataclass/parsers/nodes.py b/xsdata/formats/dataclass/parsers/nodes.py
index 8e335ce6..d7ea7135 100644
--- a/xsdata/formats/dataclass/parsers/nodes.py
+++ b/xsdata/formats/dataclass/parsers/nodes.py
@@ -34,37 +34,63 @@ Parsed = Tuple[Optional[str], Any]
 NoneStr = Optional[str]
 
 
-@dataclass
 class ElementNode(XmlNode):
-    """
-    XmlNode for complex elements and dataclasses.
-
-    :param meta: Model xml metadata
-    :param attrs: Key-value attribute mapping
-    :param ns_map: Namespace prefix-URI map
-    :param config: Parser configuration
-    :param context: Model context provider
-    :param position: The node position of objects cache
-    :param derived: The xml element is derived from a base type
-    """
+    """XmlNode for complex elements and dataclasses."""
+
+    __slots__ = (
+        "meta",
+        "attrs",
+        "ns_map",
+        "config",
+        "context",
+        "position",
+        "mixed",
+        "derived",
+        "xsi_type",
+        "assigned",
+    )
+
+    def __init__(
+        self,
+        meta: XmlMeta,
+        attrs: Dict,
+        ns_map: Dict,
+        config: ParserConfig,
+        context: XmlContext,
+        position: int,
+        mixed: bool = False,
+        derived: bool = False,
+        xsi_type: Optional[str] = None,
+    ):
+        """
+        :param meta: Model xml metadata
+        :param attrs: Key-value attribute mapping
+        :param ns_map: Namespace prefix-URI map
+        :param config: Parser configuration
+        :param context: Model context provider
+        :param position: The node position of objects cache
+        :param mixed: The node supports mixed content
+        :param derived: The xml element is derived from a base type
+        :param xsi_type: The xml type substitution
+        """
 
-    meta: XmlMeta
-    attrs: Dict
-    ns_map: Dict
-    config: ParserConfig
-    context: XmlContext
-    position: int
-    mixed: bool = False
-    derived: bool = False
-    xsi_type: Optional[str] = None
-    assigned: Set = field(default_factory=set)
+        self.meta = meta
+        self.attrs = attrs
+        self.ns_map = ns_map
+        self.config = config
+        self.context = context
+        self.position = position
+        self.mixed = mixed
+        self.derived = derived
+        self.xsi_type = xsi_type
+        self.assigned: Set[int] = set()
 
     def bind(self, qname: str, text: NoneStr, tail: NoneStr, objects: List) -> bool:
         params: Dict = {}
         text_node = False
         ParserUtils.bind_attrs(params, self.meta, self.attrs, self.ns_map)
 
-        wild_var = self.meta.find_wildcard("*")
+        wild_var = self.meta.find_any_wildcard()
         if wild_var and wild_var.mixed:
             ParserUtils.bind_mixed_objects(params, wild_var, self.position, objects)
         else:
@@ -91,11 +117,7 @@ class ElementNode(XmlNode):
 
     def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
         for var in self.meta.find_children(qname):
-            unique = None
-
-            if var.is_element and not var.list_element:
-                unique = id(var)
-
+            unique = 0 if not var.is_element or var.list_element else var.index
             if not unique or unique not in self.assigned:
                 node = self.build_node(var, attrs, ns_map, position)
 
@@ -185,7 +207,6 @@ class ElementNode(XmlNode):
         )
 
 
-@dataclass
 class WildcardNode(XmlNode):
     """
     XmlNode for extensible elements that can hold any attribute and content.
@@ -193,17 +214,23 @@ class WildcardNode(XmlNode):
     The resulting object tree will be a
     :class:`~xsdata.formats.dataclass.models.generics.AnyElement`
     instance.
-
-    :param var: Class field xml var instance
-    :param attrs: Key-value attribute mapping
-    :param ns_map: Namespace prefix-URI map
-    :param position: The node position of objects cache
     """
 
-    var: XmlVar
-    attrs: Dict
-    ns_map: Dict
-    position: int
+    __slots__ = "var", "attrs", "ns_map", "position"
+
+    def __init__(self, var: XmlVar, attrs: Dict, ns_map: Dict, position: int):
+        """
+
+        :param var: Class field xml var instance
+        :param attrs: Key-value attribute mapping
+        :param ns_map: Namespace prefix-URI map
+        :param position: The node position of objects cache
+        """
+
+        self.var = var
+        self.attrs = attrs
+        self.ns_map = ns_map
+        self.position = position
 
     def bind(self, qname: str, text: NoneStr, tail: NoneStr, objects: List) -> bool:
         children = ParserUtils.fetch_any_children(self.position, objects)
@@ -231,32 +258,36 @@ class WildcardNode(XmlNode):
         return WildcardNode(position=position, var=self.var, attrs=attrs, ns_map=ns_map)
 
 
-@dataclass
 class UnionNode(XmlNode):
     """
     XmlNode for fields with multiple possible types where at least one of them
     is a dataclass.
 
     The node will record all child events and in the end will replay
-    them and try to build all possible objects and sort them by
-    score before deciding the winner.
-
-    :param var: Class field xml var instance
-    :param attrs: Key-value attribute mapping
-    :param ns_map: Namespace prefix-URI map
-    :param position: The node position of objects cache
-    :param context: Model context provider
-    :param level: Current node level
-    :param events: Record node events
+    them and try to build all possible objects and sort them by score
+    before deciding the winner.
     """
 
-    var: XmlVar
-    attrs: Dict
-    ns_map: Dict
-    position: int
-    context: XmlContext
-    level: int = field(default_factory=int)
-    events: List = field(default_factory=list)
+    __slots__ = "var", "attrs", "ns_map", "position", "context", "level", "events"
+
+    def __init__(
+        self, var: XmlVar, attrs: Dict, ns_map: Dict, position: int, context: XmlContext
+    ):
+        """
+        :param var: Class field xml var instance
+        :param attrs: Key-value attribute mapping
+        :param ns_map: Namespace prefix-URI map
+        :param position: The node position of objects cache
+        :param context: Model context provider
+        """
+
+        self.var = var
+        self.attrs = attrs
+        self.ns_map = ns_map
+        self.position = position
+        self.context = context
+        self.level = 0
+        self.events: List[Tuple[str, str, Any, Any]] = []
 
     def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
         self.level += 1
@@ -316,17 +347,18 @@ class UnionNode(XmlNode):
             return None
 
 
-@dataclass
 class PrimitiveNode(XmlNode):
-    """
-    XmlNode for text elements with primitive values like str, int, float.
+    """XmlNode for text elements with primitive values like str, int, float."""
 
-    :param var: Class field xml var instance
-    :param ns_map: Namespace prefix-URI map
-    """
+    __slots__ = ("var", "ns_map")
 
-    var: XmlVar
-    ns_map: Dict
+    def __init__(self, var: XmlVar, ns_map: Dict):
+        """
+        :param var: Class field xml var instance
+        :param ns_map: Namespace prefix-URI map
+        """
+        self.var = var
+        self.ns_map = ns_map
 
     def bind(self, qname: str, text: NoneStr, tail: NoneStr, objects: List) -> bool:
         obj = ParserUtils.parse_value(
@@ -351,22 +383,24 @@ class PrimitiveNode(XmlNode):
         raise XmlContextError("Primitive node doesn't support child nodes!")
 
 
-@dataclass
 class StandardNode(XmlNode):
-    """
-    XmlNode for any type elements with a standard xsi:type.
+    """XmlNode for any type elements with a standard xsi:type."""
 
-    :param datatype: Standard xsi data type
-    :param ns_map: Namespace prefix-URI map
-    :param derived: Specify whether the value needs to be wrapped with
-        :class:`~xsdata.formats.dataclass.models.generics.DerivedElement`
-    :param nillable: Specify whether the node supports nillable content
-    """
+    __slots__ = ("datatype", "ns_map", "derived", "nillable")
 
-    datatype: DataType
-    ns_map: Dict
-    derived: bool
-    nillable: bool
+    def __init__(self, datatype: DataType, ns_map: Dict, derived: bool, nillable: bool):
+        """
+
+        :param datatype: Standard xsi data type
+        :param ns_map: Namespace prefix-URI map
+        :param derived: Specify whether the value needs to be wrapped with
+            :class:`~xsdata.formats.dataclass.models.generics.DerivedElement`
+        :param nillable: Specify whether the node supports nillable content
+        """
+        self.datatype = datatype
+        self.ns_map = ns_map
+        self.derived = derived
+        self.nillable = nillable
 
     def bind(self, qname: str, text: NoneStr, tail: NoneStr, objects: List) -> bool:
         obj = ParserUtils.parse_value(
@@ -394,10 +428,11 @@ class StandardNode(XmlNode):
         raise XmlContextError("Primitive node doesn't support child nodes!")
 
 
-@dataclass
 class SkipNode(XmlNode):
     """Utility node to skip parsing unknown properties."""
 
+    __slots__ = ()
+
     def child(self, qname: str, attrs: Dict, ns_map: Dict, position: int) -> XmlNode:
         """Skip nodes children are skipped as well."""
         return self
diff --git a/xsdata/models/datatype.py b/xsdata/models/datatype.py
index 98f6d7b4..c0118933 100644
--- a/xsdata/models/datatype.py
+++ b/xsdata/models/datatype.py
@@ -134,7 +134,7 @@ class XmlDate(NamedTuple):
         if args[-1] is None:
             del args[-1]
 
-        return f"{self.__class__.__name__}({', '.join(map(str, args))})"
+        return f"{self.__class__.__qualname__}({', '.join(map(str, args))})"
 
 
 class XmlDateTime(NamedTuple):
@@ -285,14 +285,14 @@ class XmlDateTime(NamedTuple):
         )
 
     def __repr__(self) -> str:
-        args = list(self)
+        args = tuple(self)
         if args[-1] is None:
-            del args[-1]
+            args = args[:-1]
 
             if args[-1] == 0:
-                del args[-1]
+                args = args[:-1]
 
-        return f"{self.__class__.__name__}({', '.join(map(str, args))})"
+        return f"{self.__class__.__qualname__}({', '.join(map(str, args))})"
 
     def __eq__(self, other: Any) -> bool:
         return cmp(self, other, operator.eq)
@@ -424,7 +424,7 @@ class XmlTime(NamedTuple):
         if args[-1] is None:
             del args[-1]
 
-        return f"{self.__class__.__name__}({', '.join(map(str, args))})"
+        return f"{self.__class__.__qualname__}({', '.join(map(str, args))})"
 
     def __eq__(self, other: Any) -> bool:
         return cmp(self, other, operator.eq)
@@ -536,24 +536,22 @@ class XmlDuration(UserString):
         if not match:
             raise ValueError(f"Invalid format '{value}'")
 
-        groups = match.groups()
-        res = TimeInterval(
-            negative=groups[0] == "-",
-            years=int(groups[1]) if groups[1] else None,
-            months=int(groups[2]) if groups[2] else None,
-            days=int(groups[3]) if groups[3] else None,
-            hours=int(groups[4]) if groups[4] else None,
-            minutes=int(groups[5]) if groups[5] else None,
-            seconds=float(groups[6]) if groups[6] else None,
+        sign, years, months, days, hours, minutes, seconds, _ = match.groups()
+        return TimeInterval(
+            negative=sign == "-",
+            years=int(years) if years else None,
+            months=int(months) if months else None,
+            days=int(days) if days else None,
+            hours=int(hours) if hours else None,
+            minutes=int(minutes) if minutes else None,
+            seconds=float(seconds) if seconds else None,
         )
 
-        return res
-
     def asdict(self) -> Dict:
         return self._interval._asdict()
 
     def __repr__(self) -> str:
-        return f'{self.__class__.__name__}("{self.data}")'
+        return f'{self.__class__.__qualname__}("{self.data}")'
 
 
 class TimePeriod(NamedTuple):
@@ -637,7 +635,7 @@ class XmlPeriod(UserString):
         return self._period._asdict()
 
     def __repr__(self) -> str:
-        return f'{self.__class__.__name__}("{self.data}")'
+        return f'{self.__class__.__qualname__}("{self.data}")'
 
     def __eq__(self, other: Any) -> bool:
         if isinstance(other, XmlPeriod):


Test patch:
diff --git a/tests/fixtures/models.py b/tests/fixtures/models.py
index 0272367a..60289cb9 100644
--- a/tests/fixtures/models.py
+++ b/tests/fixtures/models.py
@@ -28,6 +28,12 @@ class TypeD:
     z: Optional[bool]
 
 
+@dataclass
+class TypeDuplicate:
+    x: int
+    x1: str = field(metadata={"name": "x"})
+
+
 @dataclass
 class ExtendedType:
     a: Optional[TypeA] = field(default=None)
@@ -43,7 +49,7 @@ class ChoiceType:
             {"name": "a", "type": TypeA},
             {"name": "b", "type": TypeB},
             {"name": "int", "type": int},
-            {"name": "int2", "type": int},
+            {"name": "int2", "type": int, "nillable": True},
             {"name": "float", "type": float},
             {"name": "qname", "type": QName},
             {"name": "tokens", "type": List[int], "tokens": True},
@@ -59,3 +65,38 @@ class UnionType:
 @dataclass
 class AttrsType:
     attrs: Dict[str, str] = field(metadata={"type": "Attributes"})
+
+
+@dataclass
+class SequentialType:
+    a0: Optional[str] = field(default=None, metadata=dict(type="Attribute"))
+    a1: Dict[str, str] = field(default_factory=dict, metadata=dict(type="Attributes"))
+    a2: List[str] = field(
+        default_factory=list, metadata=dict(type="Attribute", tokens=True)
+    )
+    x0: Optional[int] = field(default=None)
+    x1: List[int] = field(
+        default_factory=list, metadata=dict(type="Element", sequential=True)
+    )
+    x2: List[int] = field(
+        default_factory=list, metadata=dict(type="Element", sequential=True)
+    )
+    x3: List[int] = field(
+        default_factory=list, metadata=dict(type="Element", sequential=True)
+    )
+
+
+@dataclass
+class MixedType:
+    x: int
+    y: str
+    content: List[object] = field(
+        default_factory=list,
+        metadata=dict(
+            type="Wildcard",
+            namespace="##any",
+            mixed=True,
+            min_occurs=0,
+            max_occurs=9223372036854775807,
+        ),
+    )
diff --git a/tests/formats/dataclass/models/test_builders.py b/tests/formats/dataclass/models/test_builders.py
index f523d91b..1daebdf4 100644
--- a/tests/formats/dataclass/models/test_builders.py
+++ b/tests/formats/dataclass/models/test_builders.py
@@ -101,52 +101,52 @@ class XmlMetaBuilderTests(FactoryTestCase):
         expected = [
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=0,
+                index=1,
                 name="author",
                 qname="Author",
                 types=(str,),
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=1,
+                index=2,
                 name="title",
                 qname="Title",
                 types=(str,),
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=2,
+                index=3,
                 name="genre",
                 qname="Genre",
                 types=(str,),
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=3,
+                index=4,
                 name="price",
                 qname="Price",
                 types=(float,),
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=4,
+                index=5,
                 name="pub_date",
                 qname="PubDate",
                 types=(XmlDate,),
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ELEMENT,
-                index=5,
+                index=6,
                 name="review",
                 qname="Review",
                 types=(str,),
             ),
             XmlVarFactory.create(
-                xml_type=XmlType.ATTRIBUTE, index=6, name="id", qname="ID", types=(str,)
+                xml_type=XmlType.ATTRIBUTE, index=7, name="id", qname="ID", types=(str,)
             ),
             XmlVarFactory.create(
                 xml_type=XmlType.ATTRIBUTE,
-                index=7,
+                index=8,
                 name="lang",
                 qname="LANG",
                 types=(str,),
@@ -220,7 +220,7 @@ class XmlVarBuilderTests(TestCase):
             globalns,
         )
         expected = XmlVarFactory.create(
-            index=66,
+            index=67,
             xml_type=XmlType.ELEMENTS,
             name="compound",
             qname="compound",
@@ -229,7 +229,7 @@ class XmlVarBuilderTests(TestCase):
             default=list,
             elements={
                 "{foo}node": XmlVarFactory.create(
-                    index=0,
+                    index=1,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{foo}node",
@@ -239,7 +239,7 @@ class XmlVarBuilderTests(TestCase):
                     derived=False,
                 ),
                 "{bar}x": XmlVarFactory.create(
-                    index=1,
+                    index=2,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{bar}x",
@@ -252,7 +252,7 @@ class XmlVarBuilderTests(TestCase):
                     format="Nope",
                 ),
                 "{bar}y": XmlVarFactory.create(
-                    index=2,
+                    index=3,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{bar}y",
@@ -263,7 +263,7 @@ class XmlVarBuilderTests(TestCase):
                     derived=False,
                 ),
                 "{bar}z": XmlVarFactory.create(
-                    index=3,
+                    index=4,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{bar}z",
@@ -274,7 +274,7 @@ class XmlVarBuilderTests(TestCase):
                     derived=True,
                 ),
                 "{bar}o": XmlVarFactory.create(
-                    index=4,
+                    index=5,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{bar}o",
@@ -286,7 +286,7 @@ class XmlVarBuilderTests(TestCase):
                     any_type=True,
                 ),
                 "{bar}p": XmlVarFactory.create(
-                    index=5,
+                    index=6,
                     xml_type=XmlType.ELEMENT,
                     name="compound",
                     qname="{bar}p",
@@ -298,7 +298,7 @@ class XmlVarBuilderTests(TestCase):
             },
             wildcards=[
                 XmlVarFactory.create(
-                    index=6,
+                    index=7,
                     xml_type=XmlType.WILDCARD,
                     name="compound",
                     qname="{http://www.w3.org/1999/xhtml}any",
diff --git a/tests/formats/dataclass/parsers/test_nodes.py b/tests/formats/dataclass/parsers/test_nodes.py
index 7ef5c55f..dd6d23fe 100644
--- a/tests/formats/dataclass/parsers/test_nodes.py
+++ b/tests/formats/dataclass/parsers/test_nodes.py
@@ -1,16 +1,17 @@
 import copy
 from dataclasses import dataclass
-from dataclasses import field
 from dataclasses import make_dataclass
-from dataclasses import replace
 from typing import Any
-from typing import List
 from typing import Union
 from unittest import mock
 from unittest.case import TestCase
 
 from tests.fixtures.books import BookForm
 from tests.fixtures.books import Books
+from tests.fixtures.models import MixedType
+from tests.fixtures.models import TypeA
+from tests.fixtures.models import TypeC
+from tests.fixtures.models import UnionType
 from xsdata.exceptions import ParserError
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.context import XmlContext
@@ -37,40 +38,17 @@ from xsdata.utils.testing import XmlMetaFactory
 from xsdata.utils.testing import XmlVarFactory
 
 
-@dataclass
-class Foo:
-    a: int
-    b: int
-    c: int
-
-
-@dataclass
-class FooMixed:
-    a: int
-    b: int
-    content: List[object] = field(
-        default_factory=list,
-        metadata=dict(
-            type="Wildcard",
-            namespace="##any",
-            mixed=True,
-            min_occurs=0,
-            max_occurs=9223372036854775807,
-        ),
-    )
-
-
 def add_attr(x, *args):
-    x["a"] = 1
+    x["x"] = 1
 
 
 def add_text(x, *args):
-    x["b"] = 2
+    x["y"] = "2"
     return True
 
 
 def add_child(x, *args):
-    x["c"] = 3
+    x["z"] = 3.3
 
 
 def add_content(x, *args):
@@ -81,7 +59,7 @@ class ElementNodeTests(FactoryTestCase):
     def setUp(self) -> None:
         super().setUp()
         self.context = XmlContext()
-        self.meta = XmlMetaFactory.create(clazz=Foo, qname="foo", wildcards=[])
+        self.meta = XmlMetaFactory.create(clazz=TypeC, qname="foo", wildcards=[])
         self.node = ElementNode(
             position=0,
             meta=self.meta,
@@ -108,7 +86,7 @@ class ElementNodeTests(FactoryTestCase):
 
         node = ElementNode(
             position=0,
-            meta=self.context.build(Foo),
+            meta=self.context.build(TypeC),
             context=self.context,
             config=ParserConfig(),
             attrs={"a": "b"},
@@ -119,7 +97,7 @@ class ElementNodeTests(FactoryTestCase):
 
         self.assertTrue(node.bind("foo", "text", "tail", objects))
         self.assertEqual("foo", objects[-1][0])
-        self.assertEqual(Foo(1, 2, 3), objects[-1][1])
+        self.assertEqual(TypeC(1, "2", 3.3), objects[-1][1])
 
         mock_bind_attrs.assert_called_once_with(
             mock.ANY, node.meta, node.attrs, node.ns_map
@@ -131,10 +109,9 @@ class ElementNodeTests(FactoryTestCase):
         self.assertEqual(0, mock_bind_wild_content.call_count)
 
     def test_bind_with_derived_element(self):
-        a = make_dataclass("A", fields=[])
         node = ElementNode(
             position=0,
-            meta=self.context.build(a),
+            meta=self.context.build(TypeA),
             context=self.context,
             config=ParserConfig(),
             attrs={},
@@ -144,11 +121,11 @@ class ElementNodeTests(FactoryTestCase):
 
         objects = []
 
-        self.assertTrue(node.bind("foo", None, None, objects))
+        self.assertTrue(node.bind("foo", "2", None, objects))
         self.assertEqual("foo", objects[-1][0])
-        self.assertEqual(DerivedElement("foo", a()), objects[-1][1])
+        self.assertEqual(DerivedElement("foo", TypeA(2)), objects[-1][1])
 
-    @mock.patch.object(XmlMeta, "find_wildcard")
+    @mock.patch.object(XmlMeta, "find_any_wildcard")
     @mock.patch.object(ParserUtils, "bind_objects")
     @mock.patch.object(ParserUtils, "bind_wild_content")
     @mock.patch.object(ParserUtils, "bind_content")
@@ -159,19 +136,19 @@ class ElementNodeTests(FactoryTestCase):
         mock_bind_content,
         mock_bind_wild_content,
         mock_bind_objects,
-        find_wildcard,
+        mock_find_any_wildcard,
     ):
         mock_bind_attrs.side_effect = add_attr
         mock_bind_content.return_value = False
         mock_bind_wild_content.side_effect = add_text
         mock_bind_objects.side_effect = add_child
-        find_wildcard.return_value = XmlVarFactory.create(
+        mock_find_any_wildcard.return_value = XmlVarFactory.create(
             xml_type=XmlType.WILDCARD, qname="b", name="b"
         )
 
         node = ElementNode(
             position=0,
-            meta=self.context.build(Foo),
+            meta=self.context.build(TypeC),
             context=self.context,
             config=ParserConfig(),
             attrs={"a": "b"},
@@ -182,7 +159,7 @@ class ElementNodeTests(FactoryTestCase):
 
         self.assertTrue(node.bind("foo", "text", "tail", objects))
         self.assertEqual("foo", objects[-1][0])
-        self.assertEqual(Foo(1, 2, 3), objects[-1][1])
+        self.assertEqual(TypeC(1, "2", 3.3), objects[-1][1])
 
         mock_bind_attrs.assert_called_once_with(
             mock.ANY, node.meta, node.attrs, node.ns_map
@@ -204,7 +181,7 @@ class ElementNodeTests(FactoryTestCase):
 
         node = ElementNode(
             position=0,
-            meta=self.context.build(Foo),
+            meta=self.context.build(TypeC),
             context=self.context,
             config=ParserConfig(),
             attrs={"a": "b"},
@@ -237,19 +214,19 @@ class ElementNodeTests(FactoryTestCase):
 
         node = ElementNode(
             position=0,
-            meta=self.context.build(FooMixed),
+            meta=self.context.build(MixedType),
             context=self.context,
             config=ParserConfig(),
             attrs={"a": "b"},
             ns_map={"ns0": "xsdata"},
         )
-        wildcard = node.meta.find_wildcard("*")
-        objects = [1, 2, 3]
+        wildcard = node.meta.find_any_wildcard()
+        objects = [1, "2", 3]
 
         self.assertTrue(node.bind("foo", "text", "tail", objects))
 
         self.assertEqual("foo", objects[-1][0])
-        self.assertEqual(FooMixed(1, 2, 3), objects[-1][1])
+        self.assertEqual(MixedType(1, "2", 3), objects[-1][1])
 
         mock_bind_attrs.assert_called_once_with(
             mock.ANY, node.meta, node.attrs, node.ns_map
@@ -261,7 +238,7 @@ class ElementNodeTests(FactoryTestCase):
         mock_bind_mixed_objects.assert_called_once_with(mock.ANY, wildcard, 0, objects)
 
     def test_child(self):
-        var = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", types=(Foo,))
+        var = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", types=(TypeC,))
         attrs = {"a": "b"}
         ns_map = {"ns0": "xsdata"}
         position = 1
@@ -274,9 +251,11 @@ class ElementNodeTests(FactoryTestCase):
         self.assertEqual(position, actual.position)
 
     def test_child_with_unique_element(self):
-        single = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", types=(Foo,))
+        single = XmlVarFactory.create(
+            index=1, xml_type=XmlType.ELEMENT, qname="a", types=(TypeC,)
+        )
         wildcard = XmlVarFactory.create(
-            xml_type=XmlType.WILDCARD, qname="a", types=(object,)
+            index=2, xml_type=XmlType.WILDCARD, qname="a", types=(object,)
         )
         self.meta.elements[single.qname] = [single]
         self.meta.wildcards.append(wildcard)
@@ -287,11 +266,11 @@ class ElementNodeTests(FactoryTestCase):
 
         actual = self.node.child("a", attrs, ns_map, position)
         self.assertIsInstance(actual, ElementNode)
-        self.assertIn(id(single), self.node.assigned)
+        self.assertIn(single.index, self.node.assigned)
 
         actual = self.node.child("a", attrs, ns_map, position)
         self.assertIsInstance(actual, WildcardNode)
-        self.assertNotIn(id(wildcard), self.node.assigned)
+        self.assertNotIn(wildcard.index, self.node.assigned)
 
     @mock.patch.object(ElementNode, "build_node")
     def test_child_when_failed_to_build_next_node(self, mock_build_node):
@@ -317,7 +296,7 @@ class ElementNodeTests(FactoryTestCase):
             xml_type=XmlType.ELEMENT,
             name="a",
             qname="a",
-            types=(Foo, FooMixed),
+            types=(TypeC, MixedType),
         )
         attrs = {"a": "b"}
         ns_map = {"ns0": "xsdata"}
@@ -338,7 +317,7 @@ class ElementNodeTests(FactoryTestCase):
             xml_type=XmlType.ELEMENT,
             name="a",
             qname="a",
-            types=(Foo,),
+            types=(TypeC,),
             derived=True,
         )
         xsi_type = "foo"
@@ -360,7 +339,7 @@ class ElementNodeTests(FactoryTestCase):
 
     @mock.patch.object(XmlContext, "fetch")
     def test_build_node_with_dataclass_var_validates_nillable(self, mock_ctx_fetch):
-        var = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", types=(Foo,))
+        var = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", types=(TypeC,))
         ns_map = {}
         nillable_meta = copy.deepcopy(self.meta)
         nillable_meta.nillable = True
@@ -553,7 +532,7 @@ class UnionNodeTests(TestCase):
 
         ctx = XmlContext()
         meta = ctx.build(root)
-        var = meta.find_elements("item")[0]
+        var = next(meta.find_children("item"))
         attrs = {"a": "1", "b": 2}
         ns_map = {}
         node = UnionNode(position=0, var=var, context=ctx, attrs=attrs, ns_map=ns_map)
@@ -581,19 +560,16 @@ class UnionNodeTests(TestCase):
         self.assertEqual("a", objects[-1][1])
 
     def test_bind_raises_parser_error_on_failure(self):
-        item = make_dataclass("Item", [("value", str)])
-        root = make_dataclass("Root", [("item", Union[int, item])])
-
         ctx = XmlContext()
-        meta = ctx.build(root)
-        var = meta.find_elements("item")[0]
+        meta = ctx.build(UnionType)
+        var = next(meta.find_children("element"))
 
         node = UnionNode(position=0, var=var, context=ctx, attrs={}, ns_map={})
 
         with self.assertRaises(ParserError) as cm:
-            node.bind("item", None, None, [])
+            node.bind("element", None, None, [])
 
-        self.assertEqual("Failed to parse union node: item", str(cm.exception))
+        self.assertEqual("Failed to parse union node: element", str(cm.exception))
 
 
 class PrimitiveNodeTests(TestCase):
@@ -730,25 +706,33 @@ class NodeParserTests(TestCase):
 
         attrs = {"k": "v"}
         ns_map = {"a": "b"}
-        expected_node = ElementNode(
-            position=0,
-            context=self.parser.context,
-            meta=self.parser.context.build(Books),
-            config=self.parser.config,
-            attrs=attrs,
-            ns_map=ns_map,
-        )
         self.parser.start(Books, queue, objects, "{urn:books}books", attrs, ns_map)
+        actual = queue[0]
+
         self.assertEqual(1, len(queue))
-        self.assertEqual(expected_node, queue[0])
+        self.assertEqual(0, actual.position)
+        self.assertEqual(self.parser.context, actual.context)
+        self.assertEqual(self.parser.context.build(Books), actual.meta)
+        self.assertEqual(self.parser.config, actual.config)
+        self.assertEqual(attrs, actual.attrs)
+        self.assertEqual(ns_map, actual.ns_map)
+        self.assertFalse(actual.mixed)
+        self.assertFalse(actual.derived)
+        self.assertIsNone(actual.xsi_type)
 
-        expected_node = replace(
-            expected_node, meta=self.parser.context.build(BookForm), attrs={}, ns_map={}
-        )
         self.parser.start(Books, queue, objects, "book", {}, {})
+        actual = queue[1]
 
         self.assertEqual(2, len(queue))
-        self.assertEqual(expected_node, queue[-1])
+        self.assertEqual(0, actual.position)
+        self.assertEqual(self.parser.context, actual.context)
+        self.assertEqual(self.parser.context.build(BookForm), actual.meta)
+        self.assertEqual(self.parser.config, actual.config)
+        self.assertEqual({}, actual.attrs)
+        self.assertEqual({}, actual.ns_map)
+        self.assertFalse(actual.mixed)
+        self.assertFalse(actual.derived)
+        self.assertIsNone(actual.xsi_type)
 
     def test_start_with_undefined_class(self):
         parser = self.parser
@@ -757,17 +741,19 @@ class NodeParserTests(TestCase):
 
         attrs = {"k": "v"}
         ns_map = {"a": "b"}
-        expected_node = ElementNode(
-            position=0,
-            context=parser.context,
-            meta=parser.context.build(Books),
-            config=parser.config,
-            attrs=attrs,
-            ns_map=ns_map,
-        )
         parser.start(None, queue, objects, "{urn:books}books", attrs, ns_map)
+        actual = queue[0]
+
         self.assertEqual(1, len(queue))
-        self.assertEqual(expected_node, queue[0])
+        self.assertEqual(0, actual.position)
+        self.assertEqual(self.parser.context, actual.context)
+        self.assertEqual(self.parser.context.build(Books), actual.meta)
+        self.assertEqual(self.parser.config, actual.config)
+        self.assertEqual(attrs, actual.attrs)
+        self.assertEqual(ns_map, actual.ns_map)
+        self.assertFalse(actual.mixed)
+        self.assertFalse(actual.derived)
+        self.assertIsNone(actual.xsi_type)
 
         with self.assertRaises(ParserError) as cm:
             parser.start(None, [], [], "{unknown}hopefully", {}, {})
@@ -783,19 +769,19 @@ class NodeParserTests(TestCase):
 
         attrs = {QNames.XSI_TYPE: "bk:books"}
         ns_map = {"bk": "urn:books", "xsi": Namespace.XSI.uri}
-        expected_node = ElementNode(
-            position=0,
-            context=parser.context,
-            meta=parser.context.build(Books),
-            config=parser.config,
-            attrs=attrs,
-            ns_map=ns_map,
-            derived=True,
-            xsi_type="{urn:books}books",
-        )
         parser.start(None, queue, objects, "doc", attrs, ns_map)
+        actual = queue[0]
+
         self.assertEqual(1, len(queue))
-        self.assertEqual(expected_node, queue[0])
+        self.assertEqual(0, actual.position)
+        self.assertEqual(self.parser.context, actual.context)
+        self.assertEqual(self.parser.context.build(Books), actual.meta)
+        self.assertEqual(self.parser.config, actual.config)
+        self.assertEqual(attrs, actual.attrs)
+        self.assertEqual(ns_map, actual.ns_map)
+        self.assertFalse(actual.mixed)
+        self.assertTrue(actual.derived)
+        self.assertEqual("{urn:books}books", actual.xsi_type)
 
     def test_start_with_derived_class(self):
         a = make_dataclass("a", fields=[])
@@ -809,19 +795,18 @@ class NodeParserTests(TestCase):
         ns_map = {}
         parser.start(a, queue, objects, "a", attrs, ns_map)
 
-        expected_node = ElementNode(
-            position=0,
-            context=parser.context,
-            meta=parser.context.build(b),
-            config=parser.config,
-            attrs=attrs,
-            ns_map={},
-            derived=True,
-            xsi_type="b",
-        )
+        actual = queue[0]
 
         self.assertEqual(1, len(queue))
-        self.assertEqual(expected_node, queue[-1])
+        self.assertEqual(0, actual.position)
+        self.assertEqual(parser.context, actual.context)
+        self.assertEqual(parser.context.build(b), actual.meta)
+        self.assertEqual(parser.config, actual.config)
+        self.assertEqual(attrs, actual.attrs)
+        self.assertEqual({}, actual.ns_map)
+        self.assertFalse(actual.mixed)
+        self.assertTrue(actual.derived)
+        self.assertEqual("b", actual.xsi_type)
 
     @mock.patch.object(PrimitiveNode, "bind", return_value=True)
     def test_end(self, mock_assemble):
diff --git a/tests/formats/dataclass/serializers/test_xml.py b/tests/formats/dataclass/serializers/test_xml.py
index cd8675d9..a6c860f5 100644
--- a/tests/formats/dataclass/serializers/test_xml.py
+++ b/tests/formats/dataclass/serializers/test_xml.py
@@ -1,15 +1,14 @@
 from dataclasses import dataclass
 from dataclasses import field
 from dataclasses import make_dataclass
-from typing import Dict
 from typing import Generator
 from typing import List
-from typing import Optional
 from unittest import TestCase
 from xml.etree.ElementTree import QName
 
 from tests.fixtures.books import BookForm
 from tests.fixtures.datatypes import Telephone
+from tests.fixtures.models import SequentialType
 from xsdata.exceptions import SerializerError
 from xsdata.exceptions import XmlContextError
 from xsdata.formats.dataclass.models.elements import XmlType
@@ -22,25 +21,6 @@ from xsdata.models.enums import QNames
 from xsdata.utils.testing import XmlVarFactory
 
 
-@dataclass
-class A:
-    a0: Optional[str] = field(default=None, metadata=dict(type="Attribute"))
-    a1: Dict[str, str] = field(default_factory=dict, metadata=dict(type="Attributes"))
-    a2: List[str] = field(
-        default_factory=list, metadata=dict(type="Attribute", tokens=True)
-    )
-    x0: Optional[int] = field(default=None)
-    x1: List[int] = field(
-        default_factory=list, metadata=dict(type="Element", sequential=True)
-    )
-    x2: List[int] = field(
-        default_factory=list, metadata=dict(type="Element", sequential=True)
-    )
-    x3: List[int] = field(
-        default_factory=list, metadata=dict(type="Element", sequential=True)
-    )
-
-
 class XmlSerializerTests(TestCase):
     def setUp(self) -> None:
         self.serializer = XmlSerializer()
@@ -410,11 +390,11 @@ class XmlSerializerTests(TestCase):
             name="compound",
             elements={
                 "a": XmlVarFactory.create(
-                    xml_type=XmlType.ELEMENT, qname="a", types=(A,)
+                    xml_type=XmlType.ELEMENT, qname="a", types=(SequentialType,)
                 )
             },
         )
-        value = DerivedElement(qname="a", value=A("foo"))
+        value = DerivedElement(qname="a", value=SequentialType("foo"))
         expected = [
             (XmlWriterEvent.START, "a"),
             (XmlWriterEvent.ATTR, "a0", "foo"),
@@ -516,12 +496,12 @@ class XmlSerializerTests(TestCase):
         self.assertEqual(expected, list(result))
 
     def test_next_value(self):
-        obj = A(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=[9])
-        meta = self.serializer.context.build(A)
+        obj = SequentialType(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=[9])
+        meta = self.serializer.context.build(SequentialType)
         x0 = meta.text
-        x1 = meta.find_elements("x1")[0]
-        x2 = meta.find_elements("x2")[0]
-        x3 = meta.find_elements("x3")[0]
+        x1 = next(meta.find_children("x1"))
+        x2 = next(meta.find_children("x2"))
+        x3 = next(meta.find_children("x3"))
 
         actual = self.serializer.next_value(obj, meta)
         expected = [
@@ -538,8 +518,8 @@ class XmlSerializerTests(TestCase):
         self.assertEqual(expected, list(actual))
 
     def test_next_attribute(self):
-        obj = A(a0="foo", a1={"b": "c", "d": "e"})
-        meta = self.serializer.context.build(A)
+        obj = SequentialType(a0="foo", a1={"b": "c", "d": "e"})
+        meta = self.serializer.context.build(SequentialType)
 
         actual = self.serializer.next_attribute(obj, meta, False, None)
         expected = [
diff --git a/tests/formats/dataclass/test_elements.py b/tests/formats/dataclass/test_elements.py
index a78597ad..2d0b2c72 100644
--- a/tests/formats/dataclass/test_elements.py
+++ b/tests/formats/dataclass/test_elements.py
@@ -1,5 +1,3 @@
-import copy
-from dataclasses import dataclass
 from dataclasses import make_dataclass
 from typing import Iterator
 from unittest import mock
@@ -7,24 +5,21 @@ from unittest.case import TestCase
 from xml.etree.ElementTree import QName
 
 from tests.fixtures.models import ChoiceType
+from tests.fixtures.models import ExtendedType
+from tests.fixtures.models import MixedType
 from tests.fixtures.models import TypeA
 from tests.fixtures.models import TypeB
 from tests.fixtures.models import TypeC
 from tests.fixtures.models import TypeD
+from tests.fixtures.models import TypeDuplicate
 from tests.fixtures.models import UnionType
 from xsdata.formats.dataclass.context import XmlContext
-from xsdata.formats.dataclass.models.builders import XmlMetaBuilder
 from xsdata.formats.dataclass.models.elements import XmlType
 from xsdata.formats.dataclass.models.elements import XmlVar
 from xsdata.utils.testing import XmlMetaFactory
 from xsdata.utils.testing import XmlVarFactory
 
 
-@dataclass
-class Fixture:
-    a: int
-
-
 class XmlValTests(TestCase):
     def setUp(self) -> None:
         self.context = XmlContext()
@@ -37,19 +32,14 @@ class XmlValTests(TestCase):
         var = XmlVarFactory.create(name="foo")
         self.assertIsNone(var.clazz)
 
-        var = XmlVarFactory.create(name="foo", types=(Fixture,))
-        self.assertEqual(Fixture, var.clazz)
-
-    def test_get_xml_type(self):
-        for xml_type in XmlType.all():
-            var = XmlVarFactory.create(name="foo", xml_type=xml_type)
-            self.assertEqual(xml_type, var.get_xml_type())
+        var = XmlVarFactory.create(name="foo", types=(TypeA,))
+        self.assertEqual(TypeA, var.clazz)
 
     def test_property_is_clazz_union(self):
-        var = XmlVarFactory.create(name="foo", types=(Fixture,))
+        var = XmlVarFactory.create(name="foo", types=(TypeA,))
         self.assertFalse(var.is_clazz_union)
 
-        var = XmlVarFactory.create(name="foo", types=(Fixture, int))
+        var = XmlVarFactory.create(name="foo", types=(TypeA, int))
         self.assertTrue(var.is_clazz_union)
 
     def test_property_element_types(self):
@@ -94,44 +84,19 @@ class XmlValTests(TestCase):
         self.assertEqual(var.wildcards[0], var.find_choice("{foo}a"))
 
     def test_find_value_choice(self):
-        c = make_dataclass("C", fields=[])
-        d = make_dataclass("D", fields=[], bases=(c,))
-
-        elements = [
-            XmlVarFactory.create(xml_type=XmlType.ELEMENT, name="a", types=(int,)),
-            XmlVarFactory.create(
-                xml_type=XmlType.ELEMENT, name="b", types=(int,), tokens=True
-            ),
-            XmlVarFactory.create(
-                xml_type=XmlType.ELEMENT,
-                name="c",
-                types=(c,),
-            ),
-            XmlVarFactory.create(
-                xml_type=XmlType.ELEMENT,
-                name="d",
-                types=(float,),
-                nillable=True,
-            ),
-        ]
-
-        var = XmlVarFactory.create(
-            xml_type=XmlType.ELEMENTS,
-            name="compound",
-            elements={x.qname: x for x in elements},
-        )
+        meta = self.context.build(ChoiceType)
+        var = meta.choices[0]
 
-        self.assertIsNone(var.find_value_choice("foo"))
         self.assertIsNone(var.find_value_choice(["1.1", "1.2"]))
-        self.assertEqual(elements[0], var.find_value_choice(1))
-        self.assertEqual(elements[1], var.find_value_choice([1, 2]))
-        self.assertEqual(elements[2], var.find_value_choice(d()))
-        self.assertEqual(elements[2], var.find_value_choice(c()))
-        self.assertEqual(elements[3], var.find_value_choice(None))
+        self.assertEqual(var.elements["int2"], var.find_value_choice(None))
+        self.assertEqual(var.elements["qname"], var.find_value_choice("foo"))
+        self.assertEqual(var.elements["int"], var.find_value_choice(1))
+        self.assertEqual(var.elements["tokens"], var.find_value_choice([1, 2]))
+        self.assertEqual(var.elements["a"], var.find_value_choice(TypeA(1)))
+        self.assertEqual(var.elements["b"], var.find_value_choice(TypeB(1, "b")))
 
     def test_match_namespace(self):
         var = XmlVarFactory.create(xml_type=XmlType.WILDCARD, name="foo")
-        self.assertTrue(var.match_namespace("*"))
         self.assertTrue(var.match_namespace("a"))
 
         var = XmlVarFactory.create(
@@ -161,41 +126,6 @@ class XmlValTests(TestCase):
         var.namespace_matches["{tns}cached"] = True
         self.assertTrue(var.match_namespace("{tns}cached"))
 
-    def test_eq(self):
-        var = XmlVarFactory.create(name="foo", types=(int, float))
-        clone = copy.deepcopy(var)
-        self.assertEqual(var, clone)
-
-        clone.default = 1
-        self.assertNotEqual(var, clone)
-        self.assertNotEqual(var, 1)
-        self.assertNotEqual(1, var)
-
-    def test_repr(self):
-        var = XmlVarFactory.create(name="foo", types=(int, float))
-        expected = (
-            "XmlVar("
-            "index=0, "
-            "name=foo, "
-            "qname=foo, "
-            "types=(<class 'int'>, <class 'float'>), "
-            "init=True, "
-            "mixed=False, "
-            "tokens=False, "
-            "format=None, "
-            "derived=False, "
-            "any_type=False, "
-            "nillable=False, "
-            "sequential=False, "
-            "list_element=False, "
-            "default=None, "
-            "xml_type=Element, "
-            "namespaces=(), "
-            "elements={}, "
-            "wildcards=[])"
-        )
-        self.assertEqual(expected, repr(var))
-
 
 class XmlMetaTests(TestCase):
     def setUp(self) -> None:
@@ -211,6 +141,24 @@ class XmlMetaTests(TestCase):
             any_attributes=[],
         )
 
+    def test__repr__(self):
+        expected = (
+            "XmlMeta("
+            "clazz=<class 'types.a'>, "
+            "qname='a', "
+            "source_qname='a', "
+            "nillable=False, "
+            "text=None, "
+            "choices=[], "
+            "elements={}, "
+            "wildcards=[], "
+            "attributes={}, "
+            "any_attributes=[], "
+            "namespace=None, "
+            "mixed_content=False)"
+        )
+        self.assertEqual(expected, repr(self.meta))
+
     def test_property_element_types(self):
         meta = self.context.build(UnionType)
         self.assertEqual({TypeA, TypeB, TypeC, TypeD}, meta.element_types)
@@ -225,35 +173,6 @@ class XmlMetaTests(TestCase):
         self.assertEqual(a, self.meta.find_attribute("a"))
         self.assertEqual(b, self.meta.find_attribute("b"))
 
-    def test_find_elements(self):
-        a_1 = XmlVarFactory.create(xml_type=XmlType.ATTRIBUTE, qname="a", name="a_1")
-        a_2 = XmlVarFactory.create(xml_type=XmlType.ATTRIBUTE, qname="a", name="a_2")
-
-        self.meta.elements[a_1.qname] = [a_1, a_2]
-
-        self.assertEqual([a_1, a_2], self.meta.find_elements("a"))
-        self.assertEqual([], self.meta.find_elements("b"))
-
-    @mock.patch.object(XmlVar, "find_choice")
-    def test_find_choice(self, mock_find_choice):
-        a_1 = XmlVarFactory.create(xml_type=XmlType.ATTRIBUTE, qname="a", name="a_1")
-        a_2 = XmlVarFactory.create(xml_type=XmlType.ATTRIBUTE, qname="a", name="a_2")
-
-        mock_find_choice.side_effect = [None, None, None, a_1, a_2]
-        choice_1 = XmlVarFactory.create(
-            xml_type=XmlType.ATTRIBUTE, qname="compound_1", name="compound_1"
-        )
-        choice_2 = XmlVarFactory.create(
-            xml_type=XmlType.ATTRIBUTE, qname="compound_2", name="compound_2"
-        )
-        self.meta.choices = [choice_1, choice_2]
-
-        self.assertIsNone(self.meta.find_choice("a"))
-        self.assertEqual(a_1, self.meta.find_choice("a"))
-        self.assertEqual(a_2, self.meta.find_choice("a"))
-
-        mock_find_choice.assert_has_calls([mock.call("a") for _ in range(5)])
-
     @mock.patch.object(XmlVar, "match_namespace")
     def test_find_any_attributes(self, mock_match_namespace):
         mock_match_namespace.side_effect = [False, False, False, True]
@@ -286,46 +205,28 @@ class XmlMetaTests(TestCase):
 
         mock_match_namespace.assert_has_calls([mock.call("a") for _ in range(4)])
 
-    def test_find_children(self):
-        element1 = XmlVarFactory.create(xml_type=XmlType.ELEMENT, name="a")
-        element2 = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", name="a1")
-
-        option1 = XmlVarFactory.create(xml_type=XmlType.ELEMENT, qname="a", name="a3")
-        option2 = XmlVarFactory.create(xml_type=XmlType.ELEMENT, name="b")
+    def test_find_any_wildcard(self):
+        meta = self.context.build(TypeDuplicate)
+        self.assertIsNone(meta.find_any_wildcard())
 
-        choice = XmlVarFactory.create(
-            xml_type=XmlType.ELEMENTS,
-            qname="c1",
-            name="c1",
-            elements={
-                "a": option1,
-                "b": option2,
-            },
-        )
-        wildcard = XmlVarFactory.create(
-            xml_type=XmlType.WILDCARD, qname="any", name="any"
-        )
+        meta = self.context.build(ExtendedType)
+        self.assertEqual("wildcard", meta.find_any_wildcard().qname)
 
-        self.meta.elements["a"] = [element1, element2]
-        self.meta.choices.append(choice)
-        self.meta.wildcards.append(wildcard)
+    def test_find_children(self):
+        meta = self.context.build(TypeDuplicate)
+        self.assertIsNone(next(meta.find_children("a"), None))
+        self.assertEqual(["x", "x1"], list(el.name for el in meta.find_children("x")))
 
-        result = self.meta.find_children("a")
-        self.assertIsInstance(result, Iterator)
-        self.assertEqual([element1, element2, option1, wildcard], list(result))
+        meta = self.context.build(TypeB)
+        self.assertEqual("x", next(meta.find_children("x")).qname)
+        self.assertEqual("y", next(meta.find_children("y")).qname)
 
-    def test_repr(self):
-        expected = (
-            "XmlMeta("
-            "clazz=<class 'types.a'>, "
-            "qname=a, "
-            "source_qname=a, "
-            "nillable=False, "
-            "text=None, "
-            "choices=[], "
-            "elements={}, "
-            "wildcards=[], "
-            "attributes={}, "
-            "any_attributes=[])"
-        )
-        self.assertEqual(expected, repr(self.meta))
+        meta = self.context.build(ChoiceType)
+        self.assertIsNone(next(meta.find_children("404"), None))
+        self.assertEqual("a", next(meta.find_children("a")).qname)
+        self.assertEqual("b", next(meta.find_children("b")).qname)
+        self.assertEqual("int", next(meta.find_children("int")).qname)
+
+        meta = self.context.build(MixedType)
+        self.assertEqual("content", next(meta.find_children("404")).qname)
+        self.assertTrue(next(meta.find_children("content")).is_wildcard)
diff --git a/tests/formats/test_converter.py b/tests/formats/test_converter.py
index 768c9287..54cc14ce 100644
--- a/tests/formats/test_converter.py
+++ b/tests/formats/test_converter.py
@@ -109,6 +109,21 @@ class StrConverterTests(TestCase):
         self.assertEqual("1", self.converter.serialize(1))
 
 
+class StringConverterTests(TestCase):
+    def setUp(self):
+        self.converter = converter.type_converter(str)
+
+    def test_deserialize(self):
+        string = "foo"
+        self.assertIs(string, self.converter.deserialize(string))
+        self.assertEqual("1", self.converter.deserialize(1))
+
+    def test_serialize(self):
+        string = "foo"
+        self.assertIs(string, self.converter.serialize(string))
+        self.assertEqual("1", self.converter.serialize(1))
+
+
 class BoolConverterTests(TestCase):
     def setUp(self):
         self.converter = converter.type_converter(bool)
diff --git a/tests/integration/benchmarks/test_converters.py b/tests/integration/benchmarks/test_converters.py
index bb8c18bf..93734a10 100644
--- a/tests/integration/benchmarks/test_converters.py
+++ b/tests/integration/benchmarks/test_converters.py
@@ -2,6 +2,7 @@ import pytest
 
 from xsdata.models.datatype import XmlDate
 from xsdata.models.datatype import XmlDateTime
+from xsdata.models.datatype import XmlDuration
 from xsdata.models.datatype import XmlTime
 
 
@@ -18,3 +19,8 @@ def test_xml_time(benchmark):
 @pytest.mark.benchmark(disable_gc=True, group="converters", min_rounds=100000)
 def test_xml_date(benchmark):
     benchmark(XmlDate.from_string, "2010-09-20")
+
+
+@pytest.mark.benchmark(disable_gc=True, group="converters", min_rounds=100000)
+def test_xml_duration(benchmark):
+    benchmark(XmlDuration, "P2Y6M5DT12H35M30.5S")