endojs / endo

Endo is a distributed secure JavaScript sandbox, based on SES
Apache License 2.0
762 stars 68 forks source link

perf(pass-style): Eliminate redundant work to validate passStyle shapes #2284

Closed gibson042 closed 1 month ago

gibson042 commented 1 month ago

Description

Security Considerations

None.

Scaling Considerations

The total effect is an improvement of 10% to 20% on both V8 and XS for passStyleOf(harden(largeArrayOrPlainObject)) as observed by

scripts/esbench.mjs -b3 -h'V8,*XS' \
  -M @endo/init \
  -i 'import { passStyleOf } from "@endo/pass-style"; globalThis.passStyleOf = passStyleOf;' \
  --arg len:0,1,10,100 \
  --setup 'const arr = Array(+len).fill(""), obj = Object.fromEntries(arr.map((val, i) => [`key${i}`, val]));' \
  'passStyleOf(harden(arr.slice()))' \
  'passStyleOf(harden({ ...obj }))' \
  | grep -v '^Removing '
#### Before ``` #### Moddable XS passStyleOf(harden(arr.slice())) ("0",0) 102.95928500496524 ops/ms after 81 3840-count samples passStyleOf(harden({ ...obj })) ("0",0) 99.11317008603574 ops/ms after 78 3840-count samples passStyleOf(harden(arr.slice())) ("1",0) 77.82059800664452 ops/ms after 61 3840-count samples passStyleOf(harden({ ...obj })) ("1",0) 66.47137150466045 ops/ms after 52 3840-count samples passStyleOf(harden(arr.slice())) ("10",0) 27.87037037037037 ops/ms after 98 860-count samples passStyleOf(harden({ ...obj })) ("10",0) 20.98110705999337 ops/ms after 100 633-count samples passStyleOf(harden(arr.slice())) ("100",0) 3.8361581920903953 ops/ms after 97 119-count samples passStyleOf(harden({ ...obj })) ("100",0) 2.2479338842975207 ops/ms after 100 68-count samples #### V8 passStyleOf(harden(arr.slice())) ("0",0) 312.007992007992 ops/ms after 122 7680-count samples passStyleOf(harden({ ...obj })) ("0",0) 415.27200791295746 ops/ms after 82 15360-count samples passStyleOf(harden(arr.slice())) ("1",0) 242.5531914893617 ops/ms after 95 7680-count samples passStyleOf(harden({ ...obj })) ("1",0) 260.4147877984085 ops/ms after 121 6491-count samples passStyleOf(harden(arr.slice())) ("10",0) 107.24760330578512 ops/ms after 107 3032-count samples passStyleOf(harden({ ...obj })) ("10",0) 112.47321428571429 ops/ms after 117 2907-count samples passStyleOf(harden(arr.slice())) ("100",0) 16.280052840158522 ops/ms after 104 474-count samples passStyleOf(harden({ ...obj })) ("100",0) 10.569347898047004 ops/ms after 103 310-count samples ``` #### After ``` #### Moddable XS passStyleOf(harden(arr.slice())) ("0",0) 113.61702127659575 ops/ms after 89 3840-count samples passStyleOf(harden({ ...obj })) ("0",0) 124.67703507610854 ops/ms after 103 3658-count samples passStyleOf(harden(arr.slice())) ("1",0) 84.938923737207 ops/ms after 67 3840-count samples passStyleOf(harden({ ...obj })) ("1",0) 77.62334217506631 ops/ms after 64 3658-count samples passStyleOf(harden(arr.slice())) ("10",0) 32.43941411451398 ops/ms after 104 937-count samples passStyleOf(harden({ ...obj })) ("10",0) 23.11864406779661 ops/ms after 102 682-count samples passStyleOf(harden(arr.slice())) ("100",0) 4.580838323353293 ops/ms after 102 135-count samples passStyleOf(harden({ ...obj })) ("100",0) 2.484707446808511 ops/ms after 101 74-count samples #### V8 passStyleOf(harden(arr.slice())) ("0",0) 332.46753246753246 ops/ms after 130 7680-count samples passStyleOf(harden({ ...obj })) ("0",0) 526.6577896138482 ops/ms after 206 7680-count samples passStyleOf(harden(arr.slice())) ("1",0) 265.7085828343313 ops/ms after 104 7680-count samples passStyleOf(harden({ ...obj })) ("1",0) 331.9148936170213 ops/ms after 130 7680-count samples passStyleOf(harden(arr.slice())) ("10",0) 120.50582362728785 ops/ms after 110 3292-count samples passStyleOf(harden({ ...obj })) ("10",0) 136.24742268041237 ops/ms after 112 3658-count samples passStyleOf(harden(arr.slice())) ("100",0) 17.79128137384412 ops/ms after 104 518-count samples passStyleOf(harden({ ...obj })) ("100",0) 12.364597093791282 ops/ms after 104 360-count samples ```

Documentation Considerations

None.

Testing Considerations

All existing tests still pass.

Compatibility Considerations

n/a

Upgrade Considerations

None in particular.

kriskowal commented 1 month ago

Does not need a NEWS entry. A dependent package maintainer does not need to change anything to either maintain compatibility or take advantage of the new facility.