Xpra: Ticket #1926: replace numpy dependency in websockify

As per ticket:1913#comment:2, importing numpy wastes a lot of memory and the only thing that websockify uses it for is to do a string XOR!

Let's submit a patch to make this more pluggable, we have our own code which can provide it. (our cyxor cython extension) The import would need to be deferred since the websockify module imports the sub-modules. (ie: WebSocket constructor could get the xor wrapper function from websockify.xor which we would then be able to patch up)

Alternatively, we could use the modules context hack to temporarily hide "numpy" from the module loader, then patch the _unmask method. This approach would work with older version of websockify - and they have not made any new releases in years now...

See also #1134.

Wed, 01 Aug 2018 20:39:26 GMT - Antoine Martin: owner changed

r19989 does this by pretending numpy is not installed and then monkeypatching a cython function to do the work.

This should be faster than the numpy code it replaces:

The impact should be negligible since the server doesn't do a lot of reading.

importing websockify will now show this warning:

WARNING: no 'numpy' module, HyBi protocol will be slower

This can safely be ignored.

@maxmylyn: please check that this new code does not cause any performance regressions.

Thu, 30 Aug 2018 04:31:52 GMT - Antoine Martin:

r19989 caused a regression reported in ticket:1941#comment:7 :

disconnect: zlib packet decompression failed must be string or read-only buffer, not memoryview

Fixed in r20229.

Tue, 23 Oct 2018 16:00:37 GMT - Antoine Martin:

Another regression: #2001

Wed, 16 Jan 2019 04:52:37 GMT - Antoine Martin:

See also: #2104, with websockify > 0.8 we can silence the numpy warning.

Fri, 18 Jan 2019 17:30:21 GMT - Antoine Martin: status changed; resolution set

Not heard back, so:

Sample output:

$ python ./tests/xpra/net/websockify_numpy_vs_cython.py
* slice size: 1KB
 - websockify via numpy:      119MB/s
 - xpra cython         :      635MB/s
* slice size: 8KB
 - websockify via numpy:     1189MB/s
 - xpra cython         :     4016MB/s
* slice size: 64KB
 - websockify via numpy:     3148MB/s
 - xpra cython         :     9698MB/s
* slice size: 1024KB
 - websockify via numpy:     1207MB/s
 - xpra cython         :     6416MB/s
* slice size: 16384KB
 - websockify via numpy:     1096MB/s
 - xpra cython         :     1170MB/s
* slice size: 65536KB
 - websockify via numpy:     1152MB/s
 - xpra cython         :     1254MB/s

It's much faster on smaller packets (1KB: ~5 times faster!) than on really big ones (64MB: only 10%). Typical packets are in the 1-64KB range and this is also where we benefit the most.

But I wasn't happy with those values as lz4 can compress data at that speed. So r21393 optimizes the code for better performance. Here are some results after setting cpu governor to performance:

$ python ./tests/xpra/net/websockify_numpy_vs_cython.py
* slice size: 1KB
 - xpra cython         :      899MB/s
 - websockify via numpy:      141MB/s
* slice size: 8KB
 - xpra cython         :     5330MB/s
 - websockify via numpy:     1458MB/s
* slice size: 64KB
 - xpra cython         :    14233MB/s
 - websockify via numpy:     4138MB/s
* slice size: 1024KB
 - xpra cython         :    11877MB/s
 - websockify via numpy:     4809MB/s
* slice size: 16384KB
 - xpra cython         :     3974MB/s
 - websockify via numpy:     1173MB/s
* slice size: 65536KB
 - xpra cython         :     2833MB/s
 - websockify via numpy:     1166MB/s

Note: when numpy gets vectorized optimizations (https://lwn.net/Articles/691932/), we can revisit this.

Sat, 19 Jan 2019 07:45:32 GMT - Antoine Martin: attachment set

64-bit is not faster!

Sat, 19 Jan 2019 07:45:47 GMT - Antoine Martin:

Minor enhancements in r21394 + r21395 + r21396. (unit tests, etc)

Not sure why, but the 64-bit version attached is not faster..

Wed, 23 Jan 2019 07:07:55 GMT - Antoine Martin:

Fix for building on 32-bit windows with python3: r21454.

Wed, 23 Jan 2019 17:16:24 GMT - Antoine Martin:

r21465 adds support for websockify > 0.8 in the performance test (see #2104). The results are the same or even lower than with websockify <= 0.8

See also #2121.

Sat, 23 Jan 2021 05:37:29 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1926