Skip to content

Conversation

@fabianfett
Copy link
Contributor

This pr should be rebased after #1155 has landed.
I'll post benchmark comparisons soon.

@fabianfett
Copy link
Contributor Author

================
Toolchain
================

base64-encode-1MB-toData-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       5 │       5 │       5 │       5 │       5 │       5 │       6 │    1010 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │     348 │     344 │     342 │     339 │     332 │     306 │     286 │    1010 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │    2894 │    2933 │    2949 │    2976 │    3031 │    3293 │    3519 │    1010 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-lineLength64
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       3 │       3 │       3 │       3 │       3 │       3 │       6 │     931 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │     320 │     316 │     315 │     312 │     308 │     280 │     266 │     931 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │    3150 │    3183 │    3199 │    3228 │    3273 │    3594 │    3780 │     931 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       3 │       3 │       3 │       3 │       3 │       3 │       6 │    1008 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │     346 │     342 │     340 │     338 │     335 │     318 │     313 │    1008 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │    2915 │    2947 │    2961 │    2982 │    3011 │    3156 │    3196 │    1008 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-jwtHeader-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       3 │       3 │       3 │       3 │       3 │       3 │       3 │    7056 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)    │    2574 │    2535 │    2505 │    2471 │    2417 │    2243 │    1881 │    7056 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns) *   │     409 │     415 │     420 │     425 │     435 │     467 │     540 │    7056 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

---------------------------------------------------------------------------------------------------

=============================
Existing Swift implementation
=============================

base64-encode-1MB-toData-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       2 │       2 │       2 │       2 │       2 │       2 │       2 │    3988 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    1424 │    1393 │    1382 │    1365 │    1332 │    1237 │    1047 │    3988 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     723 │     738 │     744 │     754 │     772 │     826 │     975 │    3988 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-lineLength64
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │    4170 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    1451 │    1451 │    1445 │    1439 │    1404 │    1301 │    1143 │    4170 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     708 │     709 │     712 │     715 │     733 │     788 │     886 │    4170 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │    4661 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    1624 │    1623 │    1619 │    1614 │    1592 │    1488 │    1091 │    4661 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     635 │     636 │     638 │     641 │     649 │     696 │     855 │    4661 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-jwtHeader-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │   10000 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)    │    7717 │    7707 │    7703 │    7691 │    7423 │    6571 │    4310 │   10000 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns) *   │     149 │     150 │     150 │     151 │     156 │     173 │     254 │   10000 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

---------------------------------------------------------------------------------------------------

=============================
This PR
=============================

base64-encode-1MB-toData-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       2 │       2 │       2 │       2 │       2 │       2 │       2 │    5675 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    2111 │    2057 │    2013 │    1944 │    1848 │    1674 │    1263 │    5675 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     494 │     507 │     517 │     536 │     562 │     614 │     820 │    5675 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-lineLength64
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │    5902 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    2094 │    2079 │    2067 │    2057 │    2017 │    1915 │    1589 │    5902 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     497 │     501 │     504 │     506 │     516 │     543 │     657 │    5902 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-1MB-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │    6948 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (#)    │    2532 │    2475 │    2461 │    2449 │    2387 │    2177 │    1695 │    6948 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (μs) *   │     414 │     424 │     426 │     429 │     440 │     479 │     592 │    6948 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

base64-encode-jwtHeader-toString-noOptions
╒═══════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕
│ Metric                    │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │
╞═══════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡
│ Malloc (total) *          │       1 │       1 │       1 │       1 │       1 │       1 │       1 │   10000 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Throughput (# / s) (K)    │   10004 │    9991 │    9983 │    9975 │    9687 │    8759 │    3268 │   10000 │
├───────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Time (total CPU) (ns) *   │     120 │     120 │     120 │     120 │     124 │     135 │     229 │   10000 │
╘═══════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛

@fabianfett
Copy link
Contributor Author

To analyze performance, we look at the fastest runs, as we can assume that CPU cycles that were not related to the base64 job were minimal in these situations. This allows us to make the most accurate comparisons.

  • encode-1MB-toData-noOptions

    • Baseline (in Foundation today): 2894μs
    • Swift implementation: 723μs (4x faster)
    • This PR: 494μs (5.8x faster)
  • base64-encode-1MB-toString-lineLength64

    • Baseline (in Foundation today): 3150μs
    • Swift implementation: 708μs (4.4x faster)
    • This PR: 497μs (6.3x faster)
  • base64-encode-1MB-toString-noOptions

    • Baseline (in Foundation today): 2915μs
    • Swift implementation: 635μs (4.6x faster)
    • This PR: 414μs (7x faster)
  • base64-encode-jwtHeader-toString-noOptions

    • Baseline (in Foundation today): 409ns
    • Swift implementation: 149ns (2.7x faster)
    • This PR: 120ns (3.4x faster)

I think that looks good!

@fabianfett fabianfett marked this pull request as ready for review February 4, 2025 20:06
@fabianfett fabianfett mentioned this pull request Feb 5, 2025
@fabianfett
Copy link
Contributor Author

@swift-ci please test

@fabianfett
Copy link
Contributor Author

@swift-ci please test

@fabianfett
Copy link
Contributor Author

@swift-ci please test

@parkera parkera merged commit 2c08d60 into swiftlang:main Feb 20, 2025
2 of 3 checks passed
@fabianfett fabianfett deleted the ff-faster-encoding branch February 20, 2025 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants