bartosz-antosik / vscode-spellright

Multilingual, Offline and Lightweight Spellchecker for Visual Studio Code
Other
359 stars 36 forks source link

Extension causes high cpu load #248

Open srgibson99 opened 5 years ago

srgibson99 commented 5 years ago

:warning: Make sure to attach this file from your home-directory: C:\Users\Stephen\ban.spellright-unresponsive.cpuprofile.txt :warning:

Find more details here: https://github.com/Microsoft/vscode/wiki/Explain:-extension-causes-high-cpu-load

bartosz-antosik commented 5 years ago

To deal with this in any way I need more details: What was the document spelled (size, bes if I could see the document) and what were other extensions and whether you can isolate the problem to only Spell Right extension running. Thanks for understanding.

matklad commented 5 years ago

I think I am seeing high CPU usage as well, on this document:

https://gist.github.com/matklad/1a9ffaf1231bccd350938f86bb929287

Using English Russian bilingual dictionary from here: https://github.com/titoBouzout/Dictionaries

The extension take more than 10 seconds to spell-check the document after every edit.

Extension info:

Name: Spell Right Id: ban.spellright Description: Multilingual, Offline and Lightweight Spellchecker Version: 3.0.24 Publisher: Bartosz Antosik VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=ban.spellright

Code info:

Version: 1.31.0 Commit: 7c66f58312b48ed8ca4e387ebd9ffe9605332caa Date: 2019-02-06T08:51:24.856Z Electron: 3.1.2 Chrome: 66.0.3359.181 Node.js: 10.2.0 V8: 6.6.346.32 OS: Linux x64 4.14.98

bartosz-antosik commented 5 years ago

@matklad I know Spell Right due to the back-end it uses had some problems with this particular dictionary, it is explained in more details here. Spell Right from some time allows to use more than one dictionary on the same document. Could you maybe try to use English/Russian dictionaries separately and tell me whether there is any difference?

matklad commented 5 years ago

So, using pure English dictionary is measurable faster, but still takes about 3 seconds of 100% CPU. Using only Russian or Russian + English dictionaries is more or less as bad as using the single combined dictionary.

bartosz-antosik commented 5 years ago

@matklad Thank you for the test. One last question - does this stop VSCode operation in any way? For example does VSCode react on keystrokes or freezes until end of spelling?

Another question: Spell Right is supposed on edits to spell check only a very small part around the line changed. Do I understand correctly that it takes this said 10 seconds after every small edit, e.g. one letter added/deleted?

I am on track to rebuild (although not very soon) Spell Right in language server architecture (part of the extension is run in antoher process) which may mitigate the effects of slowdowns, but what you observe is probably they way that hunspell consumes CPU to do spelling. I will try to do some more tests maybe they will show a way to do this better.

matklad commented 5 years ago

does this stop VSCode operation in any way? For example does VSCode react on keystrokes or freezes until end of spelling?

No, processing happens fully async, which is good.

Do I understand correctly that it takes this said 10 seconds after every small edit, e.g. one letter added/deleted?

Yes, specifically, after each modifications the count of the diagnostics is reset to zero and slowly grows up until the whole file is checked.

bartosz-antosik commented 5 years ago

Yes, specifically, after each modifications the count of the diagnostics is reset to zero and slowly grows up until the whole file is checked.

This sounds very strange. I will try to investigate.

bartosz-antosik commented 5 years ago

@matklad I have tested exactly the document provided and it does not cause full recheck on differential edits (e.g. when you edit something/anything in the text). I would suspect an extension conflict - e.g. some other extension does something which in chain of events causes the edit range to extend to the whole document etc.

Is there maybe a chance you could try Spell Right without any other extensions? Experiment a bit along the thesis above?

matklad commented 5 years ago

Tried with all extensions besides spellright disabled, and I still observer rechecking of the whole file

ogmios-voice commented 3 years ago

The problem is also present w/ hunspell. In an empty file w/ a single dictionary just typing very quick some random text (spaces might be needed from time to time to have separate words) will result in huge CPU usage along w/ editor hangup after 30-50 characters. With SPELLRIGHT_DEBUG_OUTPUT = true the console looks as if Spell Right is restarted for every single character typed (repeating the following lines many-many times):

console.ts:137 [Extension Host] [spellright] Adding dictionary ...
console.ts:137 [Extension Host] [spellright] RegExp prepare: author = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: title = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: subtitle = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: date = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: chapter = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: section\*? = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: subsection\*? = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: subsubsection\*? = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: part = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: paragraph = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: subparagraph = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: text(rm|sf|tt|md|bf|up|it|sl|sc|normal) = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: underline = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: emph = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: item = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: footnote(text)? = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: caption(of)? = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: multicolumn = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: href = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: hyperref = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: institute = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: frametitle = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: framesubtitle = /^undefined$/
console.ts:137 [Extension Host] [spellright] RegExp prepare: begin\{frame\} = /^undefined$/
console.ts:137 [Extension Host] [spellright] Read ... word(s) from "...\AppData\Roaming\Code\User\spellright.dict" dictionary file.
23 console.ts:137 [Extension Host] [spellright] Dictionaries path: "...\AppData\Roaming\Code\Dictionaries"
log.ts:191  WARN UNRESPONSIVE extension host, 'ban.spellright' took 77% of 2575.062ms, saved PROFILE here: '....cpuprofile' 
(7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: "42Crunch.vscode-openapi", total: 1711, percentage: 0}
1: {id: "ban.spellright", total: 1973460, percentage: 77}
2: {id: "gc", total: 1543, percentage: 0}
3: {id: "program", total: 588674, percentage: 23}
4: {id: "redhat.vscode-yaml", total: 242, percentage: 0}
5: {id: "self", total: 8883, percentage: 0}
6: {id: "vscode.merge-conflict", total: 387, percentage: 0}
length: 7
__proto__: Array(0)
ogmios-voice commented 3 years ago

Solution: step 1: optimize settings reload (right now it is reloaded on every keystroke) https://github.com/bartosz-antosik/vscode-spellright/pull/432

ogmios-voice commented 3 years ago

Performance optimization (high cpu usage fix): https://github.com/bartosz-antosik/vscode-spellright/pull/440

Performance issue:

  1. bindings.getCorrectionsForMisspelling() is very slow. This can be switched off by disabling suggestionsInHints, but while it improves startup performance, it does not solve the real issue.
  2. adjustDiagnostics will remove all diagnostics in the given line and _parser.spellCheckRange will recheck the whole line on every character change (in the given line).

The above fix will recheck only current word: no long delays even w/ suggestionsInHints on.