Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor performance on Linux #2239

Closed
hmenke opened this issue Feb 21, 2019 · 17 comments
Closed

Poor performance on Linux #2239

hmenke opened this issue Feb 21, 2019 · 17 comments

Comments

@hmenke
Copy link

hmenke commented Feb 21, 2019

Wire version: 3.6.2885 (latest from deb https://wire-app.wire.com/linux/debian stable main)
Wire for web version: -
Operating system: Debian GNU/Linux 9.8 (stretch) Linux 4.19.0-0.bpo.2-amd64
Which antivirus software do you have installed: -

What steps will reproduce the problem?

  1. Start wire-desktop
  2. Make a video call

What is the expected result?

Reasonable CPU and RAM usage.

What is the actual result?

Enormous CPU and RAM usage to an extent where the system becomes unresponsive and the frame rate of the video call drops to about 2 FPS.

Please provide any additional information below.

Screenshot of htop while I'm in the video call.

test

@hmenke
Copy link
Author

hmenke commented Feb 21, 2019

#661 might be related. I'll try the fixes proposed there but I can only confirm a duplicate once I make another video call (probably tomorrow).

@hmenke
Copy link
Author

hmenke commented Feb 22, 2019

I have applied the fix proposed in #661, namely to define the environment variable ELECTRON_FORCE_WINDOW_MENU_BAR. This improved the performance insofar that Wire now “only” uses 90% instead of 100% on all cores. The memory consumption was also improved a little and the rest of system is no longer unusable while I'm talking on Wire. Unfortunately, the Wire application itself remains barely usable. After entering the call the video frame rate drops to about 2 FPS within the first minute. The whole interface is reacting slowly.

test

@ffflorian
Copy link
Contributor

ffflorian commented Feb 22, 2019

Hi @hmenke, do I see correctly that you have ~4 GB of memory?

@hmenke
Copy link
Author

hmenke commented Feb 23, 2019

@ffflorian Yes, I have 4GB of physical memory and 10GB of swap. However, memory doesn't seem to be the problem, especially after applying the fix from #661 which improved idle performance of Wire a lot! Is there a way to profile Wire to see where it is spending the most time? Is there something like a compiler switch like -pg for GCC to generate instrumentation for gprof?

@ffflorian
Copy link
Contributor

ffflorian commented Feb 23, 2019

Is there a way to profile Wire to see where it is spending the most time? Is there something like a compiler switch like -pg for GCC to generate instrumentation for gprof?

Not as far as I know, that would be a thing for Electron to implement.

Also please note that the Linux executable is still experimental.

@adonley
Copy link

adonley commented Feb 26, 2019

I'm having an issue where leaving it running for a long period (1-2 days) will take up most of my mem and CPU (up to 12 gb of memory). I'll provide some more details next time I leave it running - looks similar to the performance problems you're having.

@hmenke
Copy link
Author

hmenke commented Feb 27, 2019

Electron (or rather V8) comes with a profiler. One can dump profiling data by starting Wire with

wire-desktop --js-flags="--prof"

This will generate a couple of isolate-<xyz>.log where <xyz> is a process ID. These can be analyzed with V8 tools. I haven't had a chance to try that yet, but I will report my findings.

Source: https://v8.dev/docs/profile

@ffflorian
Copy link
Contributor

Thanks @hmenke, I was not aware of that.

@hmenke
Copy link
Author

hmenke commented Mar 2, 2019

I have extracted the profiling from my recent Wire call. All the logs can be found below. Unfortunately, I don't know which one of these is the main process, but I think it is isolate-0x384b37dac000-v8.txt. In there I see something which is a bit worrying:

<...snip...>
 [C++]:
   ticks  total  nonlib   name
  1051554   56.2%   92.2%  poll
  36718    2.0%    3.2%  madvise
  24784    1.3%    2.2%  writev
<...snip...>

It looks like Wire is performing an enormous amount of I/O, because this generates two orders of magnitude more ticks than any other operation.


isolate-0x289ef7cf2000-v8.txt
isolate-0x289ef7cfe000-v8.txt
isolate-0x289ef7d0a000-v8.txt
isolate-0x289ef7d00000-v8.txt
isolate-0x289ef7d02000-v8.txt
isolate-0x289ef7d03000-v8.txt
isolate-0x289ef7d04000-v8.txt
isolate-0x289ef7e53000-v8.txt
isolate-0x289ef7e55000-v8.txt
isolate-0x289ef7e56000-v8.txt
isolate-0x384b37dac000-v8.txt

@hmenke
Copy link
Author

hmenke commented Mar 2, 2019

Okay, to get only a single log file you have to launch Wire with

wire-desktop --js-flags="--prof --no-logfile-per-isolate"

This will create a single v8.log.
Unfortunately, the output is also a lot less informative for some reason.

$ tick-processor v8.log
Statistical profiling result from v8.log, (46830 ticks, 0 unaccounted, 0 excluded).

 [Shared libraries]:
   ticks  total  nonlib   name
     21    0.0%          /opt/Wire/wire-desktop

 [JavaScript]:
   ticks  total  nonlib   name

 [C++]:
   ticks  total  nonlib   name
  46786   99.9%  100.0%  __pthread_cond_timedwait
      9    0.0%    0.0%  write
      2    0.0%    0.0%  v8::internal::Factory::InitializeJSObjectBody(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Map>, int)
      2    0.0%    0.0%  fwrite
      2    0.0%    0.0%  _IO_vfprintf
      1    0.0%    0.0%  mprotect
      1    0.0%    0.0%  memcpy
      1    0.0%    0.0%  fflush
      1    0.0%    0.0%  __pthread_cond_wait
      1    0.0%    0.0%  __lll_unlock_wake
      1    0.0%    0.0%  __libc_send
      1    0.0%    0.0%  __clock_gettime
      1    0.0%    0.0%  _IO_file_xsputn

 [Summary]:
   ticks  total  nonlib   name
      0    0.0%    0.0%  JavaScript
  46809  100.0%  100.0%  C++
      0    0.0%    0.0%  GC
     21    0.0%          Shared libraries

 [C++ entry points]:
   ticks    cpp   total   name
      1  100.0%    0.0%  TOTAL

 [Bottom up (heavy) profile]:
  Note: percentage shows a share of a particular caller in the total
  amount of its parent calls.
  Callers occupying less than 1.0% are not shown.

   ticks parent  name
  46786   99.9%  __pthread_cond_timedwait

@DC7IA
Copy link

DC7IA commented Oct 10, 2020

Even without a video call, Wire idles at 35 % CPU usage. That'd probably be okay on a really old CPU, but a Core i5 isn't that old. And it eats 5.8 GiB of my 8 GiB of RAM.

Again, this is just having the application running in the background seemingly not doing much.

Even running several virtual machine takes less ressources. o.O

Do we have at least a workaround since there is no fix yet?

@bennycode bennycode pinned this issue Mar 23, 2021
@charlag
Copy link

charlag commented May 4, 2021

I got pissed enough that I actually wanted to look why renderer east CPU all the time.

The answer is layer with spinner which is always there.

Screenshot from 2021-05-04 11-36-30

It triggers style recalculation and composition constantly.

I can't say we didn't have the same issue in our app but this should be fixable?

@charlag
Copy link

charlag commented May 4, 2021

I tried to modify LoadingSpinner to just return null and indeed all the repaints are gone. Silence has entered our office and my blood pressure went down.

The spinner is rendered when the account is visible:

<LoadingSpinner visible={!!account.visible} webviewRef={webviewRef} />

which it always is when it's selected I assume so it's always rendered.

@dbquarrel
Copy link

dbquarrel commented May 6, 2021

@charlag I think I love you.

Wire team, please take note that if you devote just a few resources into performance improvements it is way better for the userbase than fancy features that 1% of the users will use.

100% of the users will enjoy longer battery life and more available CPU.

@jviide
Copy link
Contributor

jviide commented Jul 6, 2021

Pull request #5164 attempts to remove the LoadingSpinner contents from the DOM after the spinner has faded out. It seems to lower the idle CPU usage considerably - at least on Macs. Huge thanks to @charlag for tracking down the culprit 🙂

@NicolasGoeddel
Copy link

Since 2022.09.20.08.41 (or 3.28.2946) Wire does not hang anymore when pasting an image into the input field. I don't know what you've changed but before I always had to wait up to 20-30 seconds (depending on the image size) until the desktop client was responsive again after pasting an screenshot. Now I can paste images within one seconds which is nice. Thanks!

@mythsunwind
Copy link
Contributor

It was indeed massively reduced with #5164 Sorry that it took so long!

@mythsunwind mythsunwind unpinned this issue Oct 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants