Comments (10)
This is good data, thanks for sharing it.
I'm happy the speedup from the performance changes is substantial. It turns out the key to doing a great job on performance is developing the initial version without paying any attention to it :)
I'll go ahead and merge the performance changes in and create new version. I can continue to iterate on performance, but elisp is just not that fast, so I think it will be hard to be equivalent to non-elisp code.
from emacs-websocket.
I haven't looked at performance at all. Half a second to consume a PNG does excessive. Was the websocket library compiled?
from emacs-websocket.
The result above is byte-compiled. Before that, it was around 700ms+. So byte-compiling brought it down to a reproducible 400ms~.
from emacs-websocket.
Can you check out the performance branch I recently created and try again? My changes should result in a substantial speedup (they did on my test).
from emacs-websocket.
Sure, I still have the code for my test.
from emacs-websocket.
That looks like a 10x improvement! From 400ms
best case to about 40ms
best case. Nice work! π
Before:
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 637ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 5ms
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 402ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 4ms
websocket-read-frame: 0ms [11 times]
websocket-read-frame: 258ms
websocket-read-frame: 0ms [18 times]
websocket-read-frame: 423ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 3ms
websocket-read-frame: 0ms [24 times]
websocket-read-frame: 231ms
websocket-read-frame: 0ms [5 times]
websocket-read-frame: 395ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 11ms
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 408ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 5ms
after
websocket-read-frame: 0ms [10 times]
websocket-read-frame: 244ms
websocket-read-frame: 0ms [19 times]
websocket-read-frame: 40ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 1ms
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 38ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 1ms
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 43ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 1ms
websocket-read-frame: 0ms [30 times]
websocket-read-frame: 40ms
websocket-read-frame: 0ms
create-image: 0ms
insert-image & redisplay: 1ms
from emacs-websocket.
I wrote a simple http server to receive the bytes directly as a POST request:
Time to receive as a simple POST binary request:
Non-byte-compiled:
image-server: receive time: 31ms
image-server: receive time: 27ms
image-server: receive time: 32ms
image-server: receive time: 27ms
image-server: receive time: 22ms
Byte-compiled, not so different:
image-server: receive time: 18ms
image-server: receive time: 24ms
image-server: receive time: 21ms
image-server: receive time: 25ms
image-server: receive time: 22ms
image-server: receive time: 23ms
from emacs-websocket.
My websocket code is like:
(progn
(websocket-server-close server)
(defvar server
(websocket-server
9009
:host 'local
:on-message
(lambda (ws frame)
(with-current-buffer (websocket-client-data ws)
(insert (websocket-frame-payload frame))
(when (websocket-frame-completep frame)
(let ((bytes (buffer-string)))
(with-current-buffer (get-buffer-create "*image-output*")
(let ((img (measure-time "create-image" (create-image bytes 'jpeg t))))
(measure-time "insert-image & redisplay"
(progn (insert-image img)
(redisplay)))))
(erase-buffer))))
)
:on-open
(lambda (ws) (message "Client connected.")
(setf (websocket-client-data ws)
(with-current-buffer
(get-buffer-create (generate-new-buffer "websocket"))
(toggle-enable-multibyte-characters -1)
(current-buffer))))
:on-close
(lambda (ws)
(kill-buffer (websocket-client-data ws))
(message "Client disconnected.")))))
from emacs-websocket.
I looked into a little bit how I'm buffering the strings.
(benchmark-run-compiled 100
(length
(with-temp-buffer
(cl-loop for i from 0 to 10000
do (insert "hello world hello worldhello worldhello worldhello worldhello world"))
(buffer-string))))
(benchmark-run-compiled 100
(length
(let ((buffer (list)))
(cl-loop for i from 0 to 10000
do (setq buffer (cons "hello world hello worldhello worldhello worldhello worldhello world" buffer)))
(mapconcat 'identity (reverse buffer) ""))))
(benchmark-run-compiled 100
(length
(let* ((buffer (list ""))
(pointer buffer))
(cl-loop for i from 0 to 10000
do (setq
pointer
(setcdr pointer
(list "hello world hello worldhello worldhello worldhello worldhello world"))))
(mapconcat 'identity buffer ""))))
(the length
is so I can easily check they all have the same length)
Results
(1.641801722 4 0.908923355999832)
(1.631438268 4 0.9008467079997899)
(1.616854798 4 0.9054001909998988)
(1.331959202 5 1.1342625530000987)
(1.322703598 5 1.119752232999872)
(1.320611183 5 1.1191802010002903)
(1.101568966 4 0.9080151119997026)
(1.085339208 4 0.9026358060000348)
(1.095221923 4 0.9009243840000636)
It seems you can shave off 30% of the time by using a list. Between consing+reverse vs setcdr, it just seems that the latter shaves off a bit more.
from emacs-websocket.
Thanks!
from emacs-websocket.
Related Issues (20)
- websocket-frame-text error HOT 1
- Add release tags HOT 3
- Custom headers in handshake HOT 4
- How to handle an error occured in `websocket-outer-filter`? HOT 6
- A single message ws.send(data); comes in as two messages HOT 5
- Randomly losing connections under emacs-ipython-notebook with version 1.11 HOT 5
- Error (websocket): in callback `on-message': JSON readtable error HOT 4
- Setting case-fold-search to nil results "Incorrect handhake from websocket" error HOT 7
- declares GPL-3+, but provided full-text license is GPL-2+ HOT 3
- Please tag a 1.12 release HOT 1
- Please consider adapting websocket-functional-test.el to use ert-deftest HOT 12
- TLSv1.3 HOT 1
- Branch rename breaks package installation HOT 6
- websocket-test.el: βfletβ is an obsolete macro (as of [emacs] 24.3) HOT 3
- websocket-to-bytes signal type error HOT 8
- Support connecting through proxies HOT 7
- infinite failure loop - emacs locked up HOT 18
- error 403 with ein over proxy HOT 14
- Push to ELPA? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emacs-websocket.