Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

@benaadams
Copy link
Member

@benaadams benaadams commented Oct 4, 2019

From dotnet/corefx#41306 (comment)

Using the enumerator for List<T> of iterating in a for introduces extra bounds checks as the length of the list is not the same as the length of the underlying array.

Marshalling to a Span first gives a fast enumerator with no additional bounds checks, and no additional bounds checks in a regular for; also can skip covarience checks.

Mostly just using it in a few places to demonstrate usage; this isn't an exhaustive or hot-path search by any means.

/cc @stephentoub

@benaadams benaadams force-pushed the CollectionsMarshal-Usage branch from 29906e7 to e721a2e Compare October 26, 2019 01:49
@benaadams
Copy link
Member Author

Feedback addressed

@jkotas
Copy link
Member

jkotas commented Oct 26, 2019

These unsafe or dangerous constructs should not be used just because of we can. Each use should be justified by measurable performance improvement.

Does this make anything measurably faster?

lock (continuationList) { }

// Operate over Span to skip extra bounds check from using List
Span<object?> continuations = CollectionsMarshal.AsSpan(continuationList);
Copy link
Member

Choose a reason for hiding this comment

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

Having more than one continuation is a rare path already. Is it really worth optimizing this? How many continuations the task needs to have to make this optimization measurable?

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed this instance; left in the swaps for List.Enumerable as the 2xsizeof(IntPtr) Span is smaller than the 3xsizeof(IntPtr) List.Enumerator and its foreach conversion to for(i<span.Length) is more efficient than the List's MoveNext+Current which additionally incurs version and additional bounds checks.

Is it really worth optimizing this?

Probably not significant relative to the continuations that are then triggered from .WaitAll; however my main motivation is: dotnet/corefx#41306 (review)

Also, presumably there are places we should be using this in corefx? I don't love adding API we can't/don't ourselves use.

Ideally; I'd find places where it has a significant impact, however I'm a little time constrained atm.

Copy link
Member

Choose a reason for hiding this comment

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

These unsafe or dangerous constructs should not be used just because of we can. Each use should be justified by measurable performance improvement.

@benaadams benaadams force-pushed the CollectionsMarshal-Usage branch from a8e0f9b to f175a37 Compare November 6, 2019 03:38
@maryamariyan
Copy link

Thank you for your contribution. As announced in dotnet/coreclr#27549 this repository will be moving to dotnet/runtime on November 13. If you would like to continue working on this PR after this date, the easiest way to move the change to dotnet/runtime is:

  1. In your coreclr repository clone, create patch by running git format-patch origin
  2. In your runtime repository clone, apply the patch by running git apply --directory src/coreclr <path to the patch created in step 1>

@maryamariyan
Copy link

Thank you for your contribution. As announced in #27549 the dotnet/runtime repository will be used going forward for changes to this code base. Closing this PR as no more changes will be accepted into master for this repository. If you’d like to continue working on this change please move it to dotnet/runtime.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants