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

Some improvement for import completion #43548

Merged
merged 19 commits into from
Oct 28, 2020

Conversation

genlu
Copy link
Member

@genlu genlu commented Apr 21, 2020

  • Added 500ms timebox to completion to unimported extension method
  • various perf improvements to reduce allocations
  • Removed text "experimental" from UI, but kept the experiment code. The plan is to disable this via experiment for all external RTW users while enable it for internal and preview users

@genlu genlu changed the base branch from master to master-vs-deps September 23, 2020 22:04
@genlu genlu changed the base branch from master-vs-deps to master September 23, 2020 22:04
@genlu genlu changed the base branch from master to master-vs-deps October 1, 2020 01:06

var builder = ArrayBuilder<MatchResult>.GetInstance();
Copy link
Member

@sharwell sharwell Oct 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 You can pass a length to GetInstance. That may or may not help here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 1. We need to show items even if they don't match filter text
// 2. No filter is selected
builder.EnsureCapacity(data.InitialSortedList.Length);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this a speculative perf change? or was this driven from some actual data? i have no problem with it either way, i'm just curious.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is addressing RPS regression caught in validation PR.

Before: +6.3mb LOH allocation
https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/VS/pullrequest/278169

After: +610kb LOH allocation
https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/VS/pullrequest/278694

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sharwell is your sdgmented array ready?

@genlu genlu changed the title Enable import completion by default Disable import completion by default Oct 21, 2020
@sharwell
Copy link
Member

Is there a reason we are removing the experiment? I'd like to go over the details with you before making this change.

@genlu genlu changed the title Disable import completion by default Some improvement for import completion Oct 21, 2020
@genlu genlu marked this pull request as ready for review October 21, 2020 22:33
@genlu genlu requested a review from a team as a code owner October 21, 2020 22:33
@genlu
Copy link
Member Author

genlu commented Oct 21, 2020

@sharwell @CyrusNajmabadi please take a look, thanks

}
}

public IEnumerator<CompletionItem> GetEnumerator()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you actually enumerate this dictionary? if so, you could consider making a struct enumrator so you save on this allocatoin as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but only once (per completion session), so it's probably no t necessary

@@ -650,6 +627,97 @@ int IEqualityComparer<ImmutableHashSet<string>>.GetHashCode(ImmutableHashSet<str
return hash;
}

private class DisplayNameToItemsMap : IEnumerable<CompletionItem>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

considre not directly exposing this as a IEnumerable. will prevent anything from going through teh interface-dispatch pathways here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by this? I'm passing this to ArrayBuilder.AddRange(), so I think the interface is required?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok. another option would be for you to enumerate this yourself, calling ArrayBuilder.Add.

But if this is only one allocation, it's nbd.

// Either the timebox is not enabled, so we need to wait until the operation for complete,
// or there's no timeout, and we now have all completion items ready.
var items = await getItemsTask.ConfigureAwait(false);
nestedTokenSource.Cancel();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this cancellation necessary? you only get here if the computation succeeded, so why do we need to cancel anything?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, this can only cancels the Delay task

@@ -23,16 +23,19 @@ internal abstract partial class AbstractTypeImportCompletionService
public Checksum Checksum { get; }

private ImmutableArray<TypeImportCompletionItemInfo> ItemInfos { get; }
private int PublicItemCount { get; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added doc. We need to exact number of items we are dealing with, since some of the optimization rely on this knowledge to avoid allocation from calls to Resize

@@ -159,6 +178,9 @@ public void AddItem(INamedTypeSymbol symbol, string containingNamespace, bool is
CompletionItemFlags.CachedAndExpanded,
extensionMethodData: null);

if (isPublic)
_publicItemCount++;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need this all doc'ed. i couldn't really undrestand what was going on.

@CyrusNajmabadi
Copy link
Member

Looking good overall. Some things i'm not sure i understand just yet.

@runfoapp runfoapp bot mentioned this pull request Oct 23, 2020
@genlu
Copy link
Member Author

genlu commented Oct 23, 2020

@CyrusNajmabadi Any more comments on this?

@genlu
Copy link
Member Author

genlu commented Oct 26, 2020

Ping @CyrusNajmabadi

@CyrusNajmabadi
Copy link
Member

can try to get to this tomorrow. please pping me then.

@genlu
Copy link
Member Author

genlu commented Oct 27, 2020

Ping @sharwell as well

@@ -577,7 +577,7 @@
<value>When on multiple lines</value>
</data>
<data name="Show_items_from_unimported_namespaces" xml:space="preserve">
<value>Show items from unimported namespaces (experimental)</value>
<value>Show items from unimported namespaces</value>
Copy link
Member

@Cosifne Cosifne Oct 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By removing the 'experiment' flag, does that mean we are plan to use the cancellation data to see if we can enable this by default for all users?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature has been stabilized for a few releases, so functionally we think we are ready to move it out of the experimental state. However, current implementation still incurs too much of perf hit for many users to justify enabling it by default. Various things contributed to this, e.g. OOP cost, some existing editor APIs is not designed for handling large amount of items, etc. We will keep making improvement and monitoring the telemetry, hopefully we can turn it on by default in a future release.

Copy link
Member

@Cosifne Cosifne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just have a few questions about the user scenarios after this change.
The optimization parts LGTM, (but I don't know how many real benefits it would have). I saw you have posted some memory data around this change. Would it also bring perf benefits? (I am guessing it might help GC)

@genlu genlu merged commit 3cf59c9 into dotnet:master-vs-deps Oct 28, 2020
@ghost ghost added this to the Next milestone Oct 28, 2020
ghost pushed a commit that referenced this pull request Oct 28, 2020
@genlu genlu deleted the EnableImportCompletion branch October 28, 2020 21:02
@allisonchou allisonchou modified the milestones: Next, 16.9.P2 Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants