Base64 performance regression in Swift 5.2 on Linux

Hi,

being the developer of swift-base64-kit I monitor base64 performance quite closely. Especially on Linux. For testing I use the official swift Docker images (5.1.5 and 5.2).

My (very simple) script for testing the performance can be found on GitHub in my repo.

Anyway it is encoding and decoding the bytes from 0...255 1m times.

Swift 5.2 results:

Number of invocations: 1000000
------------------------------------------
Encoding
Foundation | took: 411.0716909170151s
My impl    | took: 0.798367977142334s
------------------------------------------
Decoding
Foundation | took: 226.96656703948975s
My impl    | took: 0.9381359815597534s
------------------------------------------

Swift 5.1.5 results:

Number of invocations: 1000000
------------------------------------------
Encoding
Foundation | took: 25.578185081481934s
My impl    | took: 0.7761809825897217s
------------------------------------------
Decoding
Foundation | took: 2.763342022895813s
My impl    | took: 0.905689001083374s
------------------------------------------

While the performance of my implementation stayed roughly the same, we can see a 16x decrease in encoding performance in the Foundation implementation and a close to a 100x decrease in decoding performance.

What is going on here?

1 Like

I dunno what happened in 5.2 but there is this change coming in 5.3 which is meant to speed up encoding. Have you tried a master branch and compared?

CC @mishal_shah, @millenomi, @compnerd

I think the issue maybe that libFoundation.so has been compiled with -Onone ?

5.1.5 looks ok:

$ readelf -aW ~/swift-5.1.5-RELEASE-ubuntu18.04/usr/lib/swift/linux/libFoundation.so |grep Onone
$

but 5.2 shows

$ readelf -aW ~/swift-5.2-RELEASE-ubuntu18.04/usr/lib/swift/linux/libFoundation.so |grep Onone
 0x0000000000000001 (NEEDED)             Shared library: [libswiftSwiftOnoneSupport.so]

This seems to have started with swift-DEVELOPMENT-SNAPSHOT-2019-09-29 as swift-DEVELOPMENT-SNAPSHOT-2019-09-26 is not linked to it.

5 Likes

Also CC @tomerd , we need to fix this really quickly I think because if Foundation is genuinely built without optimisations that is going to make a lot of server stuff quite slow...

agreed, we should work to get a patch out asap

@compnerd@drexin looked into it, and we assumed (I think correctly?) that this ought to have been covered by:

set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")

in CMake/CMakeSwiftInformation.cmake at master · Kitware/CMake · GitHub — is that supposed to perhaps be spelled Release or similar?

It's definitely spelt correctly - my local builds are seeing -O in the flags, something else must be different. Definitely know that -O is also on the Azure builds, because it actually hit a SILGen issue recently.

Then we shall trace locally.

1 Like

@drexin and I might have something.

Could it have to do with the version of CMake used? I no longer hit SR-12394, caused by a CMake change, after updating CMake to 3.17 and rebuilding, could be a similar issue here.

I also filed this bug ([SR-12419] Large performance regression with JSONSerialization.jsonObject on Linux with Swift 5.2 · Issue #4393 · apple/swift-corelibs-foundation · GitHub) for a 10x performance regression on Linux with JSONSerialization decoding. Just pointing it out in case it's related.

I just built master using CMake 3.17.0 and it also appears to have fixed the issue with libFoundation.so. Im going to try a build of the 5.2 branch and see if that makes any difference.

1 Like

To keep everyone updated, we are actively working on resolving this issue.

10 Likes

Thank you for reporting the issue. A build system issue was introduced when we moved our implementation to CMake 3.15.2. We have issued a new release that fixes that issue. Please try again with Swift 5.2.1 for Linux from the Swift downloads page.

9 Likes