Bug 245797 - [JSC] Introduce new_array_with_species bytecode and optimize it through all tiers
Summary: [JSC] Introduce new_array_with_species bytecode and optimize it through all t...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-09-28 14:12 PDT by Jarred Sumner
Modified: 2022-10-03 18:47 PDT (History)
3 users (show)

See Also:


Attachments
array-map.mjs (1.90 KB, text/plain)
2022-09-28 14:12 PDT, Jarred Sumner
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jarred Sumner 2022-09-28 14:12:17 PDT
Created attachment 462692 [details]
array-map.mjs

A lot of modern JS uses .map and .forEach. Many codebases use these functions more frequently than for loops.

For small array literals with constant values, V8 is about 3x faster than what JSC is doing.

I've attached a benchmark script

Bun using a copy of JSC from September 17th, 2022:

cpu: Apple M1 Max
runtime: bun 0.1.14 (arm64-darwin)

benchmark                  time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------- -----------------------------
Array.map x 0           50.91 ns/iter   (45.7 ns … 274.74 ns)  47.35 ns 113.15 ns 131.34 ns
Array.map x 1           55.15 ns/iter  (51.91 ns … 453.84 ns)  52.44 ns  101.3 ns 119.57 ns
Array.map x 2            58.1 ns/iter  (51.91 ns … 183.54 ns)  52.77 ns 116.05 ns 151.96 ns
Array.map x 3           52.16 ns/iter  (46.56 ns … 152.19 ns)  47.15 ns  105.3 ns 125.74 ns
Array.map x 4           78.14 ns/iter  (51.94 ns … 164.94 ns)  83.45 ns  129.8 ns 139.77 ns
Array.map x 5           54.94 ns/iter   (51.36 ns … 226.1 ns)  53.67 ns 101.87 ns 109.88 ns
Array.map x 6           55.97 ns/iter    (51.9 ns … 257.6 ns)  54.43 ns 105.08 ns 165.98 ns
Array.map x 7            55.5 ns/iter  (51.84 ns … 162.09 ns)  54.43 ns 102.56 ns 112.98 ns
Array.map x 8           57.03 ns/iter  (51.84 ns … 476.93 ns)  54.97 ns 121.98 ns  148.4 ns
Array.map x 9            56.4 ns/iter   (51.85 ns … 370.1 ns)  54.74 ns 116.15 ns 131.97 ns
Array.map x 10          56.05 ns/iter  (51.86 ns … 212.73 ns)  54.53 ns 103.42 ns 108.92 ns
Array.map x 11          55.92 ns/iter  (51.86 ns … 187.18 ns)  54.53 ns 103.99 ns 133.61 ns
Array.map x 12          55.93 ns/iter  (51.88 ns … 272.41 ns)  54.48 ns 107.03 ns 120.77 ns
Array.map x 13          56.08 ns/iter  (51.86 ns … 174.88 ns)  54.64 ns 115.71 ns 127.24 ns
Array.map x 14          55.97 ns/iter  (51.88 ns … 191.69 ns)  54.55 ns 110.09 ns  119.5 ns
Array.map x 15          55.87 ns/iter  (51.86 ns … 357.33 ns)  54.51 ns 102.73 ns  111.7 ns
Array.map x 16          55.98 ns/iter  (51.85 ns … 181.74 ns)  54.52 ns  106.4 ns 117.05 ns
Array.map x 17          56.25 ns/iter   (51.88 ns … 380.5 ns)  54.54 ns 106.85 ns  117.7 ns
Array.map x 18          55.41 ns/iter  (51.85 ns … 127.13 ns)  54.54 ns   97.5 ns 103.66 ns
Array.map x 19          55.73 ns/iter  (51.87 ns … 267.85 ns)  54.61 ns 100.46 ns 106.79 ns
inline Array.map x 0     31.8 ns/iter   (28.91 ns … 239.6 ns)   31.2 ns  73.13 ns   84.8 ns
inline Array.map x 1     33.6 ns/iter  (30.74 ns … 106.19 ns)  33.89 ns  77.63 ns  90.15 ns
inline Array.map x 2    34.59 ns/iter  (31.94 ns … 239.49 ns)  34.82 ns   75.1 ns  85.36 ns
inline Array.map x 3    36.49 ns/iter  (33.39 ns … 151.94 ns)  36.17 ns  79.87 ns  93.93 ns
inline Array.map x 4    38.94 ns/iter   (35.6 ns … 295.58 ns)  38.79 ns  87.57 ns  93.78 ns
inline Array.map x 5    40.37 ns/iter  (36.88 ns … 268.68 ns)  39.93 ns  92.47 ns  97.58 ns
inline Array.map x 6    43.33 ns/iter  (39.58 ns … 272.25 ns)  42.77 ns  93.85 ns  101.4 ns
inline Array.map x 7    44.73 ns/iter  (40.56 ns … 505.39 ns)  43.34 ns  99.42 ns 138.26 ns
inline Array.map x 8    41.82 ns/iter  (37.98 ns … 161.33 ns)  41.22 ns   89.9 ns  98.47 ns
inline Array.map x 9     42.2 ns/iter  (38.85 ns … 104.19 ns)  41.62 ns  87.07 ns   92.6 ns
inline Array.map x 10   54.53 ns/iter  (49.97 ns … 185.29 ns)  53.61 ns  105.6 ns 113.41 ns
inline Array.map x 11   55.63 ns/iter  (50.92 ns … 251.47 ns)  54.47 ns 103.83 ns 173.58 ns
inline Array.map x 12   56.66 ns/iter  (51.74 ns … 278.88 ns)  56.14 ns 105.58 ns 107.75 ns
inline Array.map x 13   57.31 ns/iter  (52.67 ns … 212.94 ns)  56.72 ns 103.72 ns 115.22 ns
inline Array.map x 14   53.85 ns/iter   (48.2 ns … 203.39 ns)     54 ns 107.08 ns 115.79 ns
inline Array.map x 15   55.64 ns/iter  (48.61 ns … 265.81 ns)  55.93 ns 107.91 ns 114.97 ns
inline Array.map x 16   56.43 ns/iter   (49.25 ns … 408.1 ns)  55.23 ns 111.18 ns 137.67 ns
inline Array.map x 17    57.4 ns/iter  (50.05 ns … 143.59 ns)  56.14 ns  110.2 ns 116.92 ns
inline Array.map x 18   58.43 ns/iter  (51.64 ns … 267.74 ns)  58.65 ns 112.74 ns 121.68 ns
inline Array.map x 19   59.89 ns/iter    (51.9 ns … 476.5 ns)  59.19 ns 109.14 ns 112.25 ns


Node v18.9.1:

benchmark                  time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------- -----------------------------
Array.map x 0           34.04 ns/iter  (29.44 ns … 467.84 ns)  33.85 ns  42.88 ns  43.56 ns
Array.map x 1           40.11 ns/iter  (30.09 ns … 244.13 ns)   41.4 ns 109.83 ns  130.5 ns
Array.map x 2           35.94 ns/iter  (25.49 ns … 533.06 ns)  39.04 ns  47.24 ns  47.97 ns
Array.map x 3           34.42 ns/iter   (28.05 ns … 42.55 ns)  35.67 ns  39.95 ns  40.68 ns
Array.map x 4           32.94 ns/iter      (28 ns … 45.35 ns)   33.4 ns  38.43 ns  40.02 ns
Array.map x 5           36.87 ns/iter    (28.02 ns … 51.1 ns)  38.55 ns  45.81 ns  47.34 ns
Array.map x 6            34.6 ns/iter   (28.05 ns … 47.17 ns)  36.35 ns  41.41 ns  42.43 ns
Array.map x 7           32.59 ns/iter       (28 ns … 40.6 ns)  32.58 ns  37.35 ns  38.05 ns
Array.map x 8           32.49 ns/iter    (28.05 ns … 45.3 ns)   32.5 ns  36.84 ns  37.49 ns
Array.map x 9           32.61 ns/iter      (28 ns … 49.33 ns)   32.5 ns   38.6 ns  42.77 ns
Array.map x 10          32.45 ns/iter   (28.01 ns … 39.56 ns)  32.42 ns  36.15 ns  36.83 ns
Array.map x 11           34.8 ns/iter  (28.02 ns … 404.71 ns)  34.34 ns   66.5 ns  84.86 ns
Array.map x 12          32.45 ns/iter   (28.02 ns … 46.71 ns)  32.46 ns   35.9 ns  37.15 ns
Array.map x 13          32.37 ns/iter   (27.99 ns … 41.37 ns)  32.42 ns  37.14 ns  38.39 ns
Array.map x 14          32.52 ns/iter   (27.99 ns … 42.66 ns)  32.52 ns  36.39 ns   38.6 ns
Array.map x 15          31.69 ns/iter   (28.01 ns … 55.96 ns)  32.58 ns   34.9 ns  39.68 ns
Array.map x 16          30.77 ns/iter   (28.13 ns … 40.82 ns)  33.07 ns  35.27 ns  36.27 ns
Array.map x 17          30.73 ns/iter   (28.13 ns … 40.67 ns)     33 ns  35.59 ns  36.96 ns
Array.map x 18          30.77 ns/iter   (28.13 ns … 39.08 ns)   33.2 ns  34.04 ns  34.35 ns
Array.map x 19          31.03 ns/iter   (28.11 ns … 46.27 ns)  33.08 ns  37.92 ns   42.6 ns
inline Array.map x 0     7.59 ns/iter   (6.05 ns … 415.02 ns)  10.49 ns  11.85 ns  13.33 ns
inline Array.map x 1     6.01 ns/iter     (5.25 ns … 20.8 ns)   5.45 ns   10.9 ns  11.81 ns
inline Array.map x 2     7.41 ns/iter    (6.56 ns … 15.85 ns)   6.75 ns  11.69 ns  11.84 ns
inline Array.map x 3     9.02 ns/iter     (8.1 ns … 22.63 ns)   8.31 ns  13.24 ns  13.82 ns
inline Array.map x 4    11.25 ns/iter   (10.13 ns … 25.14 ns)  10.54 ns  16.12 ns  17.26 ns
inline Array.map x 5    12.33 ns/iter   (10.62 ns … 22.12 ns)  11.62 ns  16.96 ns  17.82 ns
inline Array.map x 6    13.37 ns/iter   (11.57 ns … 27.57 ns)  12.72 ns  17.59 ns   18.2 ns
inline Array.map x 7    14.45 ns/iter   (13.08 ns … 29.82 ns)  17.48 ns  19.14 ns  20.86 ns
inline Array.map x 8    15.47 ns/iter   (14.03 ns … 25.82 ns)  18.61 ns  19.32 ns  20.18 ns
inline Array.map x 9    16.58 ns/iter      (15 ns … 33.03 ns)  19.65 ns   20.6 ns   21.1 ns
inline Array.map x 10    17.6 ns/iter   (15.88 ns … 28.53 ns)  20.45 ns  22.87 ns  23.76 ns
inline Array.map x 11   18.26 ns/iter   (16.79 ns … 51.02 ns)  21.28 ns  24.35 ns  25.29 ns
inline Array.map x 12   18.79 ns/iter   (17.72 ns … 35.87 ns)  17.79 ns  23.95 ns  24.26 ns
inline Array.map x 13    19.9 ns/iter   (18.65 ns … 33.07 ns)  19.28 ns  26.57 ns  29.35 ns
inline Array.map x 14   20.79 ns/iter   (19.58 ns … 31.04 ns)  19.68 ns  25.87 ns  26.63 ns
inline Array.map x 15   21.73 ns/iter   (20.52 ns … 40.35 ns)  20.59 ns  26.63 ns  27.52 ns
inline Array.map x 16   22.82 ns/iter   (21.45 ns … 35.67 ns)   22.2 ns  29.01 ns  30.38 ns
inline Array.map x 17   23.75 ns/iter   (22.39 ns … 34.28 ns)  22.57 ns   28.8 ns  29.43 ns
inline Array.map x 18   24.75 ns/iter   (23.32 ns … 35.58 ns)  23.55 ns  29.62 ns   30.4 ns
inline Array.map x 19   25.69 ns/iter   (24.25 ns … 36.99 ns)  25.53 ns  30.86 ns  31.65 ns
Comment 1 Radar WebKit Bug Importer 2022-09-28 20:27:29 PDT
<rdar://problem/100541275>
Comment 2 Yusuke Suzuki 2022-10-01 03:39:33 PDT
WIP
cpu: unknown
runtime: unknown (unknown)

benchmark                  time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------- -----------------------------
Array.map x 0           28.49 ns/iter  (26.84 ns … 148.08 ns)  27.63 ns   59.3 ns  76.17 ns
Array.map x 1           33.21 ns/iter   (31.63 ns … 97.94 ns)  32.53 ns  62.02 ns  83.18 ns
Array.map x 2           32.17 ns/iter  (27.21 ns … 130.01 ns)  31.69 ns  73.57 ns  78.73 ns
Array.map x 3           45.48 ns/iter   (27.2 ns … 127.62 ns)  69.28 ns  81.28 ns  98.59 ns
Array.map x 4           28.96 ns/iter    (27.14 ns … 94.2 ns)  28.05 ns  64.62 ns  76.08 ns
Array.map x 5           28.55 ns/iter   (27.17 ns … 91.72 ns)  28.03 ns     39 ns   64.9 ns
Array.map x 6           28.46 ns/iter   (27.17 ns … 80.81 ns)  28.04 ns  39.17 ns  57.07 ns
Array.map x 7           28.88 ns/iter   (27.17 ns … 93.39 ns)   28.1 ns  62.61 ns  72.78 ns
Array.map x 8           29.12 ns/iter  (27.18 ns … 161.94 ns)  28.07 ns  67.97 ns  82.15 ns
Array.map x 9           28.59 ns/iter   (27.18 ns … 85.14 ns)  28.05 ns     47 ns  64.41 ns
Array.map x 10          28.52 ns/iter   (27.19 ns … 78.88 ns)  28.09 ns   39.6 ns  58.16 ns
Array.map x 11          29.13 ns/iter  (27.17 ns … 110.19 ns)  28.13 ns  79.15 ns   84.6 ns
Array.map x 12          29.03 ns/iter   (27.15 ns … 91.61 ns)  28.22 ns  65.89 ns  80.31 ns
Array.map x 13          29.14 ns/iter   (27.18 ns … 93.42 ns)  28.17 ns  69.51 ns  82.66 ns
Array.map x 14          29.16 ns/iter    (27.16 ns … 99.3 ns)  28.18 ns   70.8 ns  82.09 ns
Array.map x 15          29.07 ns/iter   (27.18 ns … 94.77 ns)  28.15 ns  65.42 ns  81.82 ns
Array.map x 16          29.27 ns/iter   (27.17 ns … 97.29 ns)   28.2 ns  71.23 ns  79.35 ns
Array.map x 17          29.23 ns/iter   (27.19 ns … 97.42 ns)  28.23 ns  67.93 ns  76.22 ns
Array.map x 18          29.18 ns/iter   (27.17 ns … 91.88 ns)  28.22 ns  71.79 ns  80.78 ns
Array.map x 19          29.26 ns/iter    (27.2 ns … 94.75 ns)  28.17 ns  71.42 ns  81.85 ns
inline Array.map x 0    32.57 ns/iter    (31.2 ns … 84.23 ns)  32.45 ns  41.88 ns  47.78 ns
inline Array.map x 1    32.66 ns/iter  (31.48 ns … 101.39 ns)   32.6 ns  42.28 ns  43.43 ns
inline Array.map x 2    33.92 ns/iter    (32.6 ns … 91.01 ns)  33.83 ns  44.92 ns  58.12 ns
inline Array.map x 3    34.96 ns/iter  (33.48 ns … 103.55 ns)  34.86 ns  45.21 ns  54.17 ns
inline Array.map x 4    37.74 ns/iter   (35.86 ns … 95.65 ns)  37.72 ns  48.17 ns  59.15 ns
inline Array.map x 5    38.56 ns/iter  (36.45 ns … 100.56 ns)  38.18 ns   54.9 ns  74.98 ns
inline Array.map x 6    29.37 ns/iter   (28.24 ns … 51.83 ns)  29.28 ns  38.95 ns  39.67 ns
inline Array.map x 7    30.77 ns/iter   (29.32 ns … 56.58 ns)  30.72 ns  40.22 ns  40.66 ns
inline Array.map x 8     27.2 ns/iter   (25.83 ns … 82.72 ns)  27.17 ns  37.07 ns  37.49 ns
inline Array.map x 9    27.97 ns/iter   (26.78 ns … 52.23 ns)  27.91 ns  37.84 ns  38.38 ns
inline Array.map x 10   34.38 ns/iter   (32.41 ns … 68.93 ns)  34.26 ns  44.48 ns  44.83 ns
inline Array.map x 11   36.91 ns/iter   (34.84 ns … 79.72 ns)  36.84 ns  47.31 ns  47.94 ns
inline Array.map x 12   36.76 ns/iter  (34.66 ns … 111.31 ns)  36.54 ns  46.86 ns  47.39 ns
inline Array.map x 13   32.41 ns/iter   (30.93 ns … 69.17 ns)  32.26 ns  43.06 ns  43.51 ns
inline Array.map x 14   33.86 ns/iter   (32.17 ns … 76.42 ns)  33.71 ns  43.96 ns  44.37 ns
inline Array.map x 15   34.65 ns/iter   (33.05 ns … 68.21 ns)  34.45 ns  44.38 ns  44.65 ns
inline Array.map x 16   35.84 ns/iter    (34.27 ns … 58.6 ns)  35.66 ns  45.48 ns  45.77 ns
inline Array.map x 17   36.43 ns/iter    (34.9 ns … 61.27 ns)  36.23 ns   46.1 ns   46.3 ns
inline Array.map x 18   37.62 ns/iter   (36.07 ns … 93.94 ns)   37.4 ns  47.55 ns  47.75 ns
inline Array.map x 19   38.46 ns/iter   (36.96 ns … 63.12 ns)  38.29 ns  47.67 ns  48.23 ns
Comment 3 Yusuke Suzuki 2022-10-02 00:01:52 PDT
Probably this is good enough since non-inline one is more important use case than inline case.
inline one can be improved if we introduce a bit more complicated MovHint analysis.

benchmark                  time (avg)             (min … max)       p75       p99      p995
------------------------------------------------------------- -----------------------------
Array.map x 0           24.54 ns/iter  (22.94 ns … 131.96 ns)   23.7 ns  52.89 ns  72.85 ns
Array.map x 1           29.48 ns/iter   (28.38 ns … 91.36 ns)  29.17 ns  39.09 ns  40.02 ns
Array.map x 2           27.35 ns/iter  (23.62 ns … 108.33 ns)  24.51 ns   68.3 ns  70.45 ns
Array.map x 3           39.27 ns/iter   (23.61 ns … 136.4 ns)  64.96 ns  76.57 ns   78.4 ns
Array.map x 4           24.36 ns/iter    (23.29 ns … 49.6 ns)  24.05 ns  34.45 ns  34.77 ns
Array.map x 5           24.56 ns/iter   (23.29 ns … 76.57 ns)  24.07 ns  36.74 ns  50.33 ns
Array.map x 6            24.4 ns/iter   (23.31 ns … 35.53 ns)   24.1 ns  34.31 ns  34.61 ns
Array.map x 7           24.61 ns/iter   (23.29 ns … 84.06 ns)   24.1 ns  34.63 ns  49.02 ns
Array.map x 8           24.47 ns/iter   (23.29 ns … 65.72 ns)  24.13 ns  34.63 ns  36.55 ns
Array.map x 9           24.39 ns/iter   (23.27 ns … 35.66 ns)  24.11 ns  34.44 ns  34.56 ns
Array.map x 10          24.46 ns/iter   (23.28 ns … 68.06 ns)  24.13 ns  34.26 ns  34.59 ns
Array.map x 11          24.45 ns/iter    (23.28 ns … 87.8 ns)  24.17 ns  34.46 ns  34.82 ns
Array.map x 12           24.5 ns/iter   (23.28 ns … 70.95 ns)  24.16 ns   34.5 ns  35.24 ns
Array.map x 13          24.47 ns/iter   (23.28 ns … 75.69 ns)  24.12 ns  34.26 ns  34.57 ns
Array.map x 14          24.54 ns/iter   (23.29 ns … 89.96 ns)  24.14 ns  34.45 ns  35.22 ns
Array.map x 15          24.47 ns/iter   (23.28 ns … 57.91 ns)  24.19 ns  34.42 ns  34.66 ns
Array.map x 16          24.62 ns/iter    (23.29 ns … 69.3 ns)  24.22 ns  34.65 ns     49 ns
Array.map x 17           24.6 ns/iter   (23.27 ns … 73.38 ns)  24.18 ns   34.9 ns   43.3 ns
Array.map x 18          24.65 ns/iter   (23.29 ns … 90.89 ns)   24.2 ns  35.15 ns  42.95 ns
Array.map x 19          24.58 ns/iter   (23.28 ns … 80.27 ns)  24.21 ns  34.79 ns  37.04 ns
inline Array.map x 0     19.7 ns/iter   (18.96 ns … 33.95 ns)   19.6 ns  28.68 ns   29.1 ns
inline Array.map x 1    23.67 ns/iter   (22.77 ns … 53.31 ns)  23.57 ns  33.13 ns  33.54 ns
inline Array.map x 2    24.75 ns/iter   (23.66 ns … 66.57 ns)  24.56 ns  35.31 ns  35.83 ns
inline Array.map x 3     26.4 ns/iter  (24.76 ns … 113.46 ns)  25.85 ns  50.35 ns  55.89 ns
inline Array.map x 4     26.9 ns/iter   (25.72 ns … 61.44 ns)   26.7 ns  36.27 ns  36.78 ns
inline Array.map x 5    26.71 ns/iter   (25.53 ns … 77.83 ns)  26.63 ns  36.52 ns  37.21 ns
inline Array.map x 6    28.69 ns/iter   (27.15 ns … 61.93 ns)  28.81 ns  38.05 ns  38.55 ns
inline Array.map x 7    32.51 ns/iter    (30.23 ns … 77.6 ns)     33 ns  44.39 ns  44.99 ns
inline Array.map x 8    26.38 ns/iter   (25.42 ns … 94.17 ns)   26.2 ns  35.94 ns  36.53 ns
inline Array.map x 9    26.95 ns/iter   (26.03 ns … 48.96 ns)  26.85 ns  36.67 ns  37.02 ns
inline Array.map x 10   29.16 ns/iter   (28.09 ns … 54.53 ns)  28.98 ns  38.25 ns  38.58 ns
inline Array.map x 11   30.03 ns/iter      (29 ns … 52.77 ns)  29.88 ns  38.81 ns   39.3 ns
inline Array.map x 12   31.15 ns/iter   (30.15 ns … 69.39 ns)  30.95 ns  39.96 ns  40.58 ns
inline Array.map x 13   31.98 ns/iter   (30.96 ns … 54.88 ns)  31.78 ns  41.58 ns  41.92 ns
inline Array.map x 14   33.01 ns/iter   (31.87 ns … 49.52 ns)  32.68 ns  42.47 ns  42.64 ns
inline Array.map x 15   33.81 ns/iter   (32.65 ns … 58.02 ns)  33.47 ns  43.13 ns  43.36 ns
inline Array.map x 16   35.03 ns/iter    (33.81 ns … 62.9 ns)  34.71 ns  44.63 ns  45.16 ns
inline Array.map x 17   35.81 ns/iter  (34.46 ns … 118.63 ns)  35.45 ns  45.33 ns  45.87 ns
inline Array.map x 18   36.77 ns/iter   (35.35 ns … 58.17 ns)  36.57 ns  46.85 ns  47.06 ns
inline Array.map x 19   37.95 ns/iter    (36.56 ns … 65.8 ns)  37.68 ns  48.07 ns  48.39 ns
Comment 4 Yusuke Suzuki 2022-10-02 00:04:26 PDT
Pull request: https://github.com/WebKit/WebKit/pull/4909
Comment 5 EWS 2022-10-03 18:47:12 PDT
Committed 255105@main (3c9c31d0fd7c): <https://commits.webkit.org/255105@main>

Reviewed commits have been landed. Closing PR #4909 and removing active labels.