IOutliner initial blocks initial opening of the document

SyntaxEditor for WPF Forum

Posted 5 years ago by Roy Versteeg
Version: 14.2.0610
Avatar

I've got some performance problems when using an IOutliner with a large document.

I've got a large document of ~10MB/100K lines. When I open this document without an Outliner the call to SetText is done within a second. But when I have an outliner with a simple TokenOutliningSourceBase it takes about 30 seconds for the document to load, and it freezes the UI thread.

I've already set the AmbientParseRequestDispatcherProvider.Dispatcher to a new ThreadedParseRequestDispatcher.

When I add this line of code to my SyntaxLanguage constructor the loading of the document goes from ~1sec to ~30sec

this.RegisterService<IOutliner>(new ActiproSoftware.Windows.Controls.SyntaxEditor.Outlining.Implementation.TokenOutliner<ScriptOutliningSource>());

 My ScriptOuliningSource implementation is as follows

protected override OutliningNodeAction GetNodeActionForToken(IToken token, out IOutliningNodeDefinition definition)
{
	switch (token.Key) 
	{
		case "MultiLineCommentStartDelimiter":
			definition = multiLineCommentDefinition;
			return OutliningNodeAction.Start;
		case "MultiLineCommentEndDelimiter":
			definition = multiLineCommentDefinition;
			return OutliningNodeAction.End;
		case "OpenCurlyBrace":
			definition = curlyBraceDefinition;
			return OutliningNodeAction.Start;
		case "CloseCurlyBrace":
			definition = curlyBraceDefinition;
			return OutliningNodeAction.End;
		default:
			definition = null;
			return OutliningNodeAction.None;
	}
}

 Is there any way to solve the problem of the blocking UI?

Comments (9)

Answer - Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Roy,

Check out the "SyntaxEditor / User Interface Features / Outlining and Collapsing Features / Outlining Sources and Outliners" topic in the documentation that comes with SyntaxEditor.  In that, it describes how while token-based outlining sources are easy to set up, they are not recommended for working with large documents since they execute in the main UI thread.  Range-based outlining sources are recommended for potentially larger documents instead since they can execute in a worker thread.


Actipro Software Support

Posted 5 years ago by Roy Versteeg
Avatar

Thanks, I must have missed that. I'll try to create an Range based outliner.

Posted 5 years ago by Roy Versteeg
Avatar

Is there any way to make Outlining virtualized? When I use an Range Based outlining source, based on the CodeOutliningRangeBased example it takes a lot of time to Parse the document. Just looping all the tokens takes up arround 30 seconds, and this has a negative effect on the parsing speed of the document ( It almost doubles in parsing time ).

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Roy,

The range-based outlining QuickStart is showing doing a full loop of the tokens, mostly because the simple Javascript language n that example doesn't have a normal syntax parser.  If you have a normal syntax parser as well as this kind of range-based data building, you are effectively reading the tokens two full times within this entire parsing phase.

What we do in our language add-ons is effectively combine the outlining data into the parse data that is produced by the parser.  We do this by building up the outlining node data as we do our syntax parsing.  That keeps the token reading down to a single loop instead of two.  Our language add-ons' outlining data actually gets built into the AST that is contructed, but you could instead have your outlining node data stored in another property on your IParseData result.  Either way, I would recommend that you find a way to build it up while syntax parsing if you do have a syntax parser for your language.


Actipro Software Support

Posted 5 years ago by Roy Versteeg
Avatar

Yes, we have an parser based on the LLParserBase, but the looping of the tokens is done by the grammar. I might be able to construct the outlining info based on the AST nodes, but i'm not sure.

Is there a way to plug in to the looping done by the parsing by the grammar we specified?

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Constructing it via AST nodes is easiest. Just make a RangeOutliningSourceBase-based class with a public method that you can call with your root parse data object.  From that, you can get your ITextSnapshot and root IAstNode.  Then make a recursive method where you pass it an IAstNode and it switches on the IAstNode.ID, calling the base class' AddNode and AddOpenNode methods when appropriate for nodes that should be outlined.  Finally in that method, enumerate through the node's Children and recursve into them.  If from within that public method you created, you call the recursive method with the root AST node that is passed, it should fully outline your tree.  You can even have optimizations such that while recursing, if you encounter something like a type member that wouldn't have any child outlining nodes, quit out of the recursive method instead of continuing to navigate into its child nodes.

There are other ways you could do things to tap into the tokens being read by the parser, but I would recommend the above since it's going to be pretty fast and is what we do for our own language add-ons.


Actipro Software Support

Posted 4 years ago by Roy Versteeg
Avatar

Constructing the outlining via the AST node as you suggested works fine as expected, only I have one problem with this approach, and that is that multi line comments are not part of the AST.

How do you handle this with your own language add-ons?

Answer - Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Roy,

Your outlining source can look at the parse data that is returned by your parser.  Normally a parser uses a token reader that filters out the comment tokens from ever reaching the parser.  What you can do is if your token reader encounters a multi-line comment, store its range in a collection of multi-line comment ranges on the parse data.  Then have your outlining source take those ranges into account when creating outlining nodes, along with the AST structure.


Actipro Software Support

Posted 4 years ago by Roy Versteeg
Avatar

Thanks, i now build my entire outlining structure in the token reader, which performs just fine.

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.