Page 1 of 2

Empty RVE and Addict Autospell = 100% CPU

Posted: Mon Aug 22, 2011 8:27 pm
by Marsianin
When Addict4 spell checker is set to autocheck while typing with empty RichViewEdit CPU usage is almost 100%
Typing 1-2 letters in RVE and it became normal.
Is there a way to fix it?

Posted: Tue Aug 23, 2011 9:42 am
by Sergey Tkachenko
Addict's live spellcheck does not work for TRichView at all.
Use TRichView.OnSpellingCheck event instead.

Posted: Tue Aug 23, 2011 10:27 pm
by Marsianin
This is why I'm writing it here and not in addict forums.
I'm using RichViewEdit1.StartLiveSpelling; and running this on empty document produces high CPU usage.
Typing something brings CPU back to normal.

Posted: Wed Aug 24, 2011 1:17 pm
by Sergey Tkachenko
I do not know how it's possible. The live spelling thread must be suspended very quickly for long document. And OnSpellingCheck should not be called even once.
Try to trace TRVWordEnumThread.Execute.

Posted: Wed Aug 24, 2011 5:40 pm
by Marsianin
It's not for long document, it's for empty one.
I'm calling StartLiveSpelling (if enabled in my program's options) every time I clear or load new document into RVE.
And calling it just after creating a new document (clearing previous one) consumes CPU. Empty document, maybe 1 default style, no items...

Posted: Wed Aug 24, 2011 5:58 pm
by Sergey Tkachenko
I cannot reproduce the problem.
For any case, make sure that you call this method after calling Format.

Posted: Wed Aug 24, 2011 9:47 pm
by Marsianin
It happens just after this code (ClearRVE):

Code: Select all

  RichViewEdit1.Clear;
  RVStyle1.TextStyles.Clear;
  with RVStyle1.TextStyles.Add do begin
    FontName:=EditorFontName;
    Size:=EditorFontSize;
    Color:=DefTextColor;
  end;
  RVStyle1.ParaStyles.Clear;
  RVStyle1.ParaStyles.Add;
  RVStyle1.ListStyles.Clear;
  RichViewEdit1.BackgroundStyle:=bsNoBitmap;
  RichViewEdit1.BackgroundBitmap:=nil;
  RichViewEdit1.Color:=EditorDefColor;
  RichViewEdit1.LeftMargin:=3;
  RichViewEdit1.RightMargin:=3;
  RichViewEdit1.TopMargin:=3;
  RichViewEdit1.BottomMargin:=3;
  RichViewEdit1.MinTextWidth:=0;
  RichViewEdit1.MaxTextWidth:=0;
  RichViewEdit1.BiDiMode:=rvbdUnspecified;
  RichViewEdit1.Format;
  FontNameCombo.ItemIndex:=FontNameCombo.Items.IndexOf(EditorFontName);
  FontSizeCombo.Text:=IntToStr(EditorFontSize);
  StylesCombo.ItemIndex:=0;
  RichViewEdit1.ApplyStyleConversion(TEXT_APPLYSTYLE);
  RVRuler1.UpdateRulerIndents;
  RVRuler1.UpdateRulerMargins;
  RVRuler1.AdjustPosition;
If I comment RichViewEdit1.ApplyStyleConversion(TEXT_APPLYSTYLE); it does not consumes CPU. Why?

Posted: Fri Aug 26, 2011 11:28 am
by Sergey Tkachenko
Unfortunately, I cannot reproduce this problem.
May be for some reason TRVWordEnumThread.Execute runs in a cycle instead of suspending itself, but I do not know why it can happen :(
May be you try to trace this procedure and see how many cycles it makes?

Posted: Fri Aug 26, 2011 6:59 pm
by Marsianin
Looks like something happens just after RichViewEdit1.ApplyStyleConversion(TEXT_APPLYSTYLE) which applies default style to an empty RVE.
Because disabling this code does not consumes CPU.
Anyway I'll try to play more with this...

Posted: Sat Aug 27, 2011 6:03 am
by Sergey Tkachenko
I think this method just starts a live spelling thread (if LiveSpellingMode = rvlspOnChange). Although, a code in OnStyleConversion event may be important.

Posted: Mon Aug 29, 2011 5:49 am
by Marsianin
You're right. Changed LiveSpellingMode to rvlspManualStart and everything works fine without CPU consumption. Anyway I start auto spell checking manually.

But I think it's a bug...

Posted: Thu Jul 05, 2012 9:00 pm
by JonRobertson
We just implemented LiveSpelling with Addict a couple of days ago and we were seeing this same issue, although our scenario was a little different.

If our TRichViews were empty, we were not seeing a race condition. But if our TRichViews had content (loaded with InsertRVFFromStreamEd), then we'd see a race condition. (I know I shouldn't be using InsertRVFFromStreamEd, but I get Index Out of Range errors if I use other methods and I haven't figure that out yet.)

We have a form that contains multiple TRichViews. In one particular scenario there are four or five TRichViews, each with content. Our app would race all four of the CPUs in my quad-core machine.

I was calling StartLiveSpelling after Format because I read somewhere that was the approach to take. I didn't know about LiveSpellingMode until your post and didn't realize it defaulted to rvlspOnChange.

If I comment out my calls to StartLiveSpelling, the CPU race went away. (And yet I was confused why LiveSpelling was still working, until now :)) If I change LiveSpellingMode to rvlspManualStart and leave in my calls to StartLiveSpelling, the CPU race also goes away.

Posted: Fri Jul 06, 2012 11:30 am
by Sergey Tkachenko
The threads may really take a lot of CPU time when working. If CPU does not have other work to do, why not to complete checking ASAP? But they have the lowest priority and I believe they do not slow down other operations too much. Am I right?
After finishing checking, the thread is not deleted but suspended.

Posted: Fri Jul 06, 2012 11:39 am
by JonRobertson
This isn't what we saw. Our QA team suspected something was wrong because of how slow the form was behaving. This form is a core piece of our new release. The form has been in development for the past month, with new functionality gradually added during that time. QA has been testing the form heavily for the last couple of weeks, while development continues.

QA noticed a couple of days ago that the form suddenly was not as responsive as it was. It was sluggish and operations that previously were instantaneous were taking a couple of seconds at times. The slowness wasn't seen just in the TRichViewEdits, it was seen throughout the app when this form was open.

As I mentioned, the CPU on all four of my processors would race at 99% and would stay there as long as the form was open. The app was not locked up, but performance was impacted.

Once I set LiveSpellingMode to rvlspManualStart on each TRichViewEdit, the CPU was no longer racing and our performance returned to how it was.

This isn't the impact of the work that LiveSpelling is "supposed" to do. LiveSpelling is working for us and it works fairly quickly (these TRichViewEdits have very little content). This is a thread race condition that is abnormal.

If it is important to you, I can spend some time trying to determine what TRVWordEnumThread is doing to cause the CPU to race at 99%. But it'll be a few days before I can spend additional time on it.

Posted: Fri Jul 06, 2012 6:55 pm
by Sergey Tkachenko
I have a guess.
We recently found a bug: if StartLiveSpelling is called (almost) immediately after some editing operation (or an editing method), and this editing operation already started a live spelling (it happens if LiveSpellingMode=rvlspOnChange), then StartLiveSpelling does not restart checking, but puts the thread in a waste cycle.

As a quick fix you can either change LiveSpellingMode or do not call StartLiveSpelling.
We plan to upload a fixed version in the next week.