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

Optimize Pipe.DefaultPipeWriter GetSpan and Advance #29837

Merged
merged 5 commits into from
May 23, 2018

Conversation

ahsonkhan
Copy link

  • Memory.Slice.Span is slightly slower than Memory.Span.Slice (GetSpan helper gets the span first before slicing).
  • Removing the second (length) parameter from Slice since it isn't necessary.
  • I am assuming that Advance(bytesWritten = 0) is not a common scenario, so we shrink the method size by not creating a separate code path for it and save a branch.

cc @pakrym, @davidfowl, @benaadams

}

// Slice the AvailableMemory to the WritableBytes size
int end = _writingHead.End;
Memory<byte> availableMemory = _writingHead.AvailableMemory;
availableMemory = availableMemory.Slice(end, availableMemory.Length - end);
Span<byte> availableMemory = _writingHead.AvailableMemory.Span;
Copy link
Member

Choose a reason for hiding this comment

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

nit: availableMemory => availableSpan

Copy link

Choose a reason for hiding this comment

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

Don't use _writingHead outside the lock

Copy link
Member

Choose a reason for hiding this comment

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

Was used previously outside lock?

Copy link

Choose a reason for hiding this comment

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

Good time to stop :)

Copy link

Choose a reason for hiding this comment

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

Or wait, it's not supposed to be syncronised.

@pakrym
Copy link

pakrym commented May 22, 2018

Any perf numbers?

@ahsonkhan
Copy link
Author

ahsonkhan commented May 22, 2018

Any perf numbers?

I don't know of any relevant benchmarks that exist today that will help with this (at this scale). Any ideas which ones to run and compare? Nano benchmarks, measuring each of the methods in isolation show small improvements (~10%).

BenchmarkDotNet=v0.10.14, OS=Windows 10.0.16299.431 (1709/FallCreatorsUpdate/Redstone3)
Intel Xeon CPU E5-1620 v2 3.70GHz, 1 CPU, 8 logical and 4 physical cores
Frequency=3604598 Hz, Resolution=277.4234 ns, Timer=TSC
.NET Core SDK=2.1.300-rtm-008866
  [Host]     : .NET Core 2.1.0-rtm-26516-03 (CoreCLR 4.6.26516.03, CoreFX 4.6.26516.03), 64bit RyuJIT
  DefaultJob : .NET Core 2.1.0-rtm-26516-03 (CoreCLR 4.6.26516.03, CoreFX 4.6.26516.03), 64bit RyuJIT

If marked with AggressiveInlining attribute:

Method Mean Error StdDev Scaled ScaledSD
GetMemorySpan 3.728 ns 0.0300 ns 0.0234 ns 1.00 0.00
GetSpanDirectly 3.254 ns 0.0973 ns 0.1121 ns 0.87 0.03

If not inlined:

Method Mean Error StdDev Scaled
GetMemorySpan 13.275 ns 0.0895 ns 0.0699 ns 1.00
GetSpanDirectly 4.238 ns 0.1177 ns 0.1488 ns 0.32
Method Mean Error StdDev Scaled ScaledSD
GetSegmentSizeOriginal 2.926 ns 0.0296 ns 0.0262 ns 1.00 0.00
GetSegmentSizeNew 2.865 ns 0.0571 ns 0.0506 ns 0.98 0.02
Method Mean Error StdDev Scaled
GetMemoryOriginal 24.42 ns 0.0568 ns 0.0531 ns 1.00
GetMemoryNew 21.67 ns 0.1069 ns 0.0947 ns 0.89

@ahsonkhan ahsonkhan merged commit f189356 into dotnet:master May 23, 2018
@ahsonkhan ahsonkhan deleted the OptimizeGetSpan branch May 23, 2018 00:31
@karelz karelz added this to the 3.0 milestone Jun 2, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
)

* Optimize DefaultPipeWriter GetSpan

* Some code refactoring and additional optimizations

* Remove unnecessary length calculation when slicing memory.

* Address PR feedback.


Commit migrated from dotnet/corefx@f189356
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.

4 participants