emacs-jupyter / jupyter

An interface to communicate with Jupyter kernels.
GNU General Public License v3.0
933 stars 92 forks source link

emacs-jupyter REPL less efficient with network traffic than browser REPL #245

Open robsmith11 opened 4 years ago

robsmith11 commented 4 years ago

The emacs-jupyter REPL is very nice, but I've noticed the response times are much slower than the browser-based REPL when using a remote server on a high-latency connection (300-500ms ping in this case).

To show the difference I ran a simple command (2+2) on a Julia REPL first with the emacs-jupyter REPL and then with the browser based REPL (run in Chromium). As you can see from the timings, emacs-jupyter required 6 network round-trips before the result was returned, while the browser REPL only required a 2 round-trips.

Is there any way to make emacs-jupyter as efficient as the browser REPL?

emacs-jupyter:

$ sudo tshark -i wlan0 -f 'port 9999'
Running as user "root" and group "root". This could be dangerous.
Capturing on 'wlan0'
    1 0.000000000 192.168.43.2 → remote_server HTTP 668 GET /api/kernels/17b3528f-e356-REDACTED HTTP/1.1
    2 0.571063489 remote_server → 192.168.43.2 HTTP 553 HTTP/1.1 200 OK  (application/json)
    3 0.572480104 192.168.43.2 → remote_server TCP 66 57424 → 9999 [ACK] Seq=603 Ack=488 Win=533 Len=0 TSval=32271981 TSecr=70964842
    4 0.590802552 192.168.43.2 → remote_server TCP 378 57637 → 9999 [PSH, ACK] Seq=1 Ack=1 Win=498 Len=312 TSval=32271983 TSecr=70935714
    5 0.681523958 remote_server → 192.168.43.2 TCP 68 9999 → 57637 [PSH, ACK] Seq=1 Ack=1 Win=501 Len=2 TSval=70965040 TSecr=32269026
    6 0.682592500 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=313 Ack=3 Win=498 Len=0 TSval=32271992 TSecr=70965040
    7 0.896143802 remote_server → 192.168.43.2 TCP 66 9999 → 57637 [ACK] Seq=3 Ack=313 Win=501 Len=0 TSval=70965255 TSecr=32271983
    8 0.897298489 192.168.43.2 → remote_server TCP 72 57637 → 9999 [PSH, ACK] Seq=313 Ack=3 Win=498 Len=6 TSval=32272013 TSecr=70965255
    9 0.899128177 remote_server → 192.168.43.2 TCP 1454 9999 → 57637 [ACK] Seq=3 Ack=313 Win=501 Len=1388 TSval=70965258 TSecr=32271983
   10 0.899630885 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=319 Ack=1391 Win=509 Len=0 TSval=32272013 TSecr=70965258
   11 0.961658177 remote_server → 192.168.43.2 TCP 605 9999 → 57637 [PSH, ACK] Seq=1391 Ack=313 Win=501 Len=539 TSval=70965319 TSecr=32271992
   12 0.962634323 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=319 Ack=1930 Win=520 Len=0 TSval=32272020 TSecr=70965319
   13 1.595764999 remote_server → 192.168.43.2 TCP 66 9999 → 57637 [ACK] Seq=1930 Ack=319 Win=501 Len=0 TSval=70965552 TSecr=32271992
   14 1.596910572 192.168.43.2 → remote_server TCP 473 57637 → 9999 [PSH, ACK] Seq=319 Ack=1930 Win=520 Len=407 TSval=32272083 TSecr=70965552
   15 2.210509739 remote_server → 192.168.43.2 TCP 66 9999 → 57637 [ACK] Seq=1930 Ack=726 Win=501 Len=0 TSval=70966316 TSecr=32272083
   16 2.210533749 remote_server → 192.168.43.2 TCP 694 9999 → 57637 [PSH, ACK] Seq=1930 Ack=726 Win=501 Len=628 TSval=70966318 TSecr=32272083
   17 2.211312499 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=726 Ack=2558 Win=531 Len=0 TSval=32272145 TSecr=70966318
   18 2.210554843 remote_server → 192.168.43.2 TCP 1454 9999 → 57637 [ACK] Seq=2558 Ack=726 Win=501 Len=1388 TSval=70966320 TSecr=32272083
   19 2.211752603 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=726 Ack=3946 Win=542 Len=0 TSval=32272145 TSecr=70966320
   20 2.824581874 remote_server → 192.168.43.2 TCP 1334 9999 → 57637 [PSH, ACK] Seq=3946 Ack=726 Win=501 Len=1268 TSval=70966859 TSecr=32272145
   21 2.825502968 192.168.43.2 → remote_server TCP 66 57637 → 9999 [ACK] Seq=726 Ack=5214 Win=553 Len=0 TSval=32272206 TSecr=70966859

browser REPL:

[me@s3 ~]$ sudo tshark -i wlan0 -f 'port 9999'
Running as user "root" and group "root". This could be dangerous.
Capturing on 'wlan0'
    1 0.000000000 192.168.43.2 → remote_server TCP 72 59745 → 9999 [PSH, ACK] Seq=1 Ack=1 Win=374 Len=6 TSval=32543351 TSecr=73677474
    2 0.005905209 remote_server → 192.168.43.2 TCP 66 9999 → 59745 [ACK] Seq=1 Ack=7 Win=501 Len=0 TSval=73678155 TSecr=32543273
    3 0.457176823 192.168.43.2 → remote_server TCP 510 59743 → 9999 [PSH, ACK] Seq=1 Ack=1 Win=422 Len=444 TSval=32543396 TSecr=73675658
    4 0.462031198 remote_server → 192.168.43.2 TCP 78 [TCP Dup ACK 2#1] 9999 → 59745 [ACK] Seq=1 Ack=7 Win=501 Len=0 TSval=73678917 TSecr=32543351 SLE=1 SRE=7
    5 1.126585885 remote_server → 192.168.43.2 TCP 66 9999 → 59743 [ACK] Seq=1 Ack=445 Win=501 Len=0 TSval=73679416 TSecr=32543396
    6 1.127092708 remote_server → 192.168.43.2 TCP 690 9999 → 59743 [PSH, ACK] Seq=1 Ack=445 Win=501 Len=624 TSval=73679418 TSecr=32543396
    7 1.127105521 remote_server → 192.168.43.2 TCP 1454 9999 → 59743 [ACK] Seq=625 Ack=445 Win=501 Len=1388 TSval=73679420 TSecr=32543396
    8 1.127888542 192.168.43.2 → remote_server TCP 66 59743 → 9999 [ACK] Seq=445 Ack=2013 Win=444 Len=0 TSval=32543463 TSecr=73679418

Obviously the exact timings depend on the current network conditions and other idiosyncrasies, but from repeating the command many times, I'd estimate that it takes 2-3x longer on average to get results from emacs-jupyter than with the browser.

failable commented 2 years ago

I feel about 500ms delay to have a response when pressing an Enter with empty input, is it related to this?

nnicandro commented 2 years ago

I wonder if this has to do with the fact that emacs-jupyter sends an is_complete_request to the kernel first and only after the kernel says the code is complete is an execute_request sent.

Do you know where the code for the browser based REPL is located?

failable commented 2 years ago

What happens if we don't have this is_complete_request?

nnicandro commented 2 years ago

If we got rid of the is_complete_request we wouldn't be able to rely on the kernel to tell us if RET produces a new line in the REPL or sends an execute_request to the kernel. We would probably have to specify RET as just entering a new line and add S-RET to send an execute_request similar to a Jupyter notebook.

failable commented 2 years ago

Thanks for the explanation.

Although the Jupyter notebook way is a bit different from the traditional comint way, I will vote it if it could speed up the input experience. Can we have an option for this?