跳到主要内容

Announcing InversifyJS 8.1.3

· 阅读需 5 分钟
Roberto Pintos López
InversifyJS maintainer

We're happy to announce InversifyJS 8.1.3, a release focused on performance optimizations in the container resolution path.

Dependency injection is rarely the bottleneck in a well-designed application, so we do not want to oversell microbenchmark wins as a universal upgrade story. That said, if your codebase relies on complex transient services or resolves large object graphs repeatedly, this release can reduce overhead in the places where container work is actually visible.

The benchmarks below were taken from packages/container/tools/container-benchmarks/src/bin/run.ts and compare the current implementation against previous InversifyJS releases.

[CJS] Running benchmarks...

Get service in singleton scope
┌─────────┬────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'inversifyCurrent' │ '256.36 ± 0.17%' │ '240.00 ± 10.00' │ '4085114 ± 0.01%' │ '4166667 ± 166667' │ 3900747 │
│ 1 │ 'inversify6' │ '1115.0 ± 0.27%' │ '1022.0 ± 30.00' │ '945343 ± 0.03%' │ '978474 ± 27903' │ 896894 │
│ 2 │ 'inversify7' │ '314.98 ± 0.14%' │ '291.00 ± 9.00' │ '3296324 ± 0.01%' │ '3436426 ± 103093' │ 3174774 │
│ 3 │ 'inversify8' │ '276.02 ± 0.13%' │ '260.00 ± 10.00' │ '3766103 ± 0.01%' │ '3846154 ± 142450' │ 3622979 │
│ 4 │ 'awilix' │ '233.92 ± 0.34%' │ '211.00 ± 9.00' │ '4561593 ± 0.01%' │ '4739337 ± 193882' │ 4274933 │
│ 5 │ 'NestJS' │ '327.08 ± 0.36%' │ '301.00 ± 9.00' │ '3211162 ± 0.01%' │ '3322259 ± 96453' │ 3057333 │
│ 6 │ 'tsyringe' │ '309.53 ± 0.31%' │ '290.00 ± 10.00' │ '3385338 ± 0.01%' │ '3448276 ± 123153' │ 3230725 │
└─────────┴────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
inversifyCurrent vs inversify6 Speedup: 4.321x
inversifyCurrent vs inversify7 Speedup: 1.239x
inversifyCurrent vs inversify8 Speedup: 1.085x
inversifyCurrent vs awilix Speedup: 0.896x
inversifyCurrent vs NestJS Speedup: 1.272x
inversifyCurrent vs tsyringe Speedup: 1.207x

Get service in transient scope
┌─────────┬────────────────────┬──────────────────┬───────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼────────────────────┼──────────────────┼───────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'inversifyCurrent' │ '281.41 ± 0.25%' │ '261.00 ± 10.00' │ '3702193 ± 0.01%' │ '3831418 ± 141381' │ 3553538 │
│ 1 │ 'inversify6' │ '5750.8 ± 0.28%' │ '5350.0 ± 80.00' │ '180996 ± 0.05%' │ '186916 ± 2754' │ 173890 │
│ 2 │ 'inversify7' │ '609.69 ± 0.15%' │ '581.00 ± 10.00' │ '1690669 ± 0.01%' │ '1721170 ± 30143' │ 1640183 │
│ 3 │ 'inversify8' │ '445.85 ± 0.28%' │ '401.00 ± 10.00' │ '2386816 ± 0.02%' │ '2493766 ± 60676' │ 2242894 │
│ 4 │ 'awilix' │ '449.01 ± 0.38%' │ '421.00 ± 10.00' │ '2323630 ± 0.01%' │ '2375297 ± 55111' │ 2227134 │
│ 5 │ 'NestJS' │ '11058 ± 1.98%' │ '9397.0 ± 290.00' │ '100822 ± 0.10%' │ '106417 ± 3377' │ 90431 │
│ 6 │ 'tsyringe' │ '468.15 ± 0.16%' │ '441.00 ± 10.00' │ '2213899 ± 0.01%' │ '2267574 ± 52612' │ 2136062 │
└─────────┴────────────────────┴──────────────────┴───────────────────┴────────────────────────┴────────────────────────┴─────────┘
inversifyCurrent vs inversify6 Speedup: 20.455x
inversifyCurrent vs inversify7 Speedup: 2.190x
inversifyCurrent vs inversify8 Speedup: 1.551x
inversifyCurrent vs awilix Speedup: 1.593x
inversifyCurrent vs NestJS Speedup: 36.720x
inversifyCurrent vs tsyringe Speedup: 1.672x

Get complex service in singleton scope
┌─────────┬────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'inversifyCurrent' │ '264.21 ± 0.25%' │ '250.00 ± 9.00' │ '3931347 ± 0.01%' │ '4000000 ± 149378' │ 3784803 │
│ 1 │ 'inversify6' │ '1120.0 ± 1.66%' │ '1022.0 ± 30.00' │ '943130 ± 0.02%' │ '978474 ± 28806' │ 892870 │
│ 2 │ 'inversify7' │ '315.64 ± 0.37%' │ '291.00 ± 10.00' │ '3331150 ± 0.01%' │ '3436426 ± 114167' │ 3168127 │
│ 3 │ 'inversify8' │ '286.70 ± 0.36%' │ '261.00 ± 9.00' │ '3668124 ± 0.01%' │ '3831418 ± 127714' │ 3487997 │
│ 4 │ 'awilix' │ '258.01 ± 0.26%' │ '241.00 ± 10.00' │ '4047521 ± 0.01%' │ '4149378 ± 165314' │ 3875780 │
│ 5 │ 'NestJS' │ '335.19 ± 0.15%' │ '311.00 ± 10.00' │ '3088769 ± 0.01%' │ '3215434 ± 100169' │ 2983398 │
│ 6 │ 'tsyringe' │ '319.12 ± 0.31%' │ '300.00 ± 10.00' │ '3274949 ± 0.01%' │ '3333333 ± 107527' │ 3133607 │
└─────────┴────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
inversifyCurrent vs inversify6 Speedup: 4.168x
inversifyCurrent vs inversify7 Speedup: 1.180x
inversifyCurrent vs inversify8 Speedup: 1.072x
inversifyCurrent vs awilix Speedup: 0.971x
inversifyCurrent vs NestJS Speedup: 1.273x
inversifyCurrent vs tsyringe Speedup: 1.200x

Get complex service in transient scope
┌─────────┬─────────────────────────────────────┬───────────────────┬───────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼─────────────────────────────────────┼───────────────────┼───────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'inversifyCurrent' │ '72890 ± 0.67%' │ '68157 ± 2084.0' │ '14239 ± 0.20%' │ '14672 ± 452' │ 13720 │
│ 1 │ 'inversifyCurrent (Resolved Value)' │ '76522 ± 0.46%' │ '74499 ± 1523.0' │ '13289 ± 0.13%' │ '13423 ± 274' │ 13069 │
│ 2 │ 'inversify6' │ '5389772 ± 2.50%' │ '5120533 ± 57307' │ '189 ± 1.44%' │ '195 ± 2' │ 186 │
│ 3 │ 'inversify7' │ '317547 ± 0.74%' │ '306793 ± 2199.5' │ '3198 ± 0.28%' │ '3260 ± 23' │ 3150 │
│ 4 │ 'inversify8' │ '181530 ± 0.62%' │ '176230 ± 751.00' │ '5575 ± 0.17%' │ '5674 ± 24' │ 5509 │
│ 5 │ 'awilix' │ '280252 ± 0.34%' │ '274372 ± 2154.0' │ '3588 ± 0.18%' │ '3645 ± 29' │ 3569 │
│ 6 │ 'NestJS' │ '81098 ± 1.65%' │ '72105 ± 1392.0' │ '13213 ± 0.24%' │ '13869 ± 269' │ 12331 │
│ 7 │ 'tsyringe' │ '226590 ± 0.43%' │ '220552 ± 2736.0' │ '4454 ± 0.20%' │ '4534 ± 57' │ 4414 │
└─────────┴─────────────────────────────────────┴───────────────────┴───────────────────┴────────────────────────┴────────────────────────┴─────────┘
inversifyCurrent vs inversifyCurrent (Resolved Value) Speedup: 1.071x
inversifyCurrent vs inversify6 Speedup: 75.489x
inversifyCurrent vs inversify7 Speedup: 4.452x
inversifyCurrent vs inversify8 Speedup: 2.554x
inversifyCurrent vs awilix Speedup: 3.969x
inversifyCurrent vs NestJS Speedup: 1.078x
inversifyCurrent vs tsyringe Speedup: 3.197x

Get complex async service in transient scope
┌─────────┬────────────────────┬───────────────────┬───────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼────────────────────┼───────────────────┼───────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'inversifyCurrent' │ '368917 ± 0.83%' │ '353280 ± 7113.0' │ '2767 ± 0.38%' │ '2831 ± 57' │ 2711 │
│ 1 │ 'inversify6' │ '5036349 ± 2.42%' │ '4741104 ± 94917' │ '202 ± 1.50%' │ '211 ± 4' │ 199 │
│ 2 │ 'inversify7' │ '720247 ± 0.83%' │ '699286 ± 5881.0' │ '1405 ± 0.42%' │ '1430 ± 12' │ 1389 │
│ 3 │ 'inversify8' │ '592877 ± 0.98%' │ '569894 ± 7464.0' │ '1718 ± 0.47%' │ '1755 ± 23' │ 1687 │
└─────────┴────────────────────┴───────────────────┴───────────────────┴────────────────────────┴────────────────────────┴─────────┘
inversifyCurrent vs inversify6 Speedup: 13.689x
inversifyCurrent vs inversify7 Speedup: 1.969x
inversifyCurrent vs inversify8 Speedup: 1.610x

What improved

The strongest improvements show up when resolving transient services:

  • Get service in transient scope: 281.41 ns average latency, about 1.58x faster than InversifyJS 8.0
  • Get complex service in transient scope: 72,890 ns average latency, about 2.49x faster than InversifyJS 8.0
  • Get complex async service in transient scope: 368,917 ns average latency, about 1.61x faster than InversifyJS 8.0

Singleton resolution also improved modestly:

  • Get service in singleton scope: 256.36 ns average latency, about 1.08x faster than InversifyJS 8.0
  • Get complex service in singleton scope: 264.21 ns average latency, about 1.09x faster than InversifyJS 8.0

For reference, the current implementation also remains significantly faster than InversifyJS 6 and 7 in the scenarios we benchmarked, especially in transient-heavy workloads.

What this means for you

If your application mostly resolves a few long-lived services, you may not notice a dramatic end-to-end change. If, however, you build plugin systems, request-scoped graphs, or other transient-heavy designs, this release should shave off some container overhead without requiring any code changes.

As always, benchmark data should be read in context. Measure your own application if you want to understand where the real bottlenecks are, but if container resolution is part of that profile, 8.1.3 should be a worthwhile upgrade.

Thanks for trying out InversifyJS 8.1.3, and please let us know if you run into any issues.