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

Add a Lines(this string) extensions method #52

Merged
merged 7 commits into from
Aug 22, 2022
Merged

Conversation

snowfrogdev
Copy link
Contributor

This method is inspired by rust's String.lines() method.

I've decided to make this method return a IEnumerable<ReadOnlyMemory<char>> instead of an IEnumerable<string> because there is a non-negligeable performance gain in doing so.

I've compared three different ways of splitting a string on new lines, here are the benchmarks:

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.22000
12th Gen Intel Core i9-12900K, 1 CPU, 24 logical and 16 physical cores
.NET Core SDK=6.0.303
 [Host]     : .NET Core 6.0.8 (CoreCLR 6.0.822.36306, CoreFX 6.0.822.36306), X64 RyuJIT
 DefaultJob : .NET Core 6.0.8 (CoreCLR 6.0.822.36306, CoreFX 6.0.822.36306), X64 RyuJIT

Method N Mean Error StdDev Ratio RatioSD Gen 0 Gen 1 Gen 2 Allocated
LinesSplit 1 17.925 ms 0.3575 ms 0.9480 ms 1.00 0.00 687.5000 406.2500 125.0000 9556.79 KB
LinesSubstring 1 13.590 ms 0.2694 ms 0.5254 ms 0.74 0.04 703.1250 421.8750 140.6250 9081.89 KB
LinesMemory 1 13.551 ms 0.1991 ms 0.1554 ms 0.74 0.03 703.1250 421.8750 140.6250 9081.97 KB
LinesSplit 5 15.722 ms 0.3055 ms 0.3637 ms 1.00 0.00 687.5000 406.2500 140.6250 9174.87 KB
LinesSubstring 5 5.350 ms 0.1062 ms 0.1304 ms 0.34 0.01 562.5000 281.2500 - 8699.88 KB
LinesMemory 5 3.831 ms 0.0466 ms 0.0413 ms 0.24 0.01 117.1875 58.5938 - 1825.64 KB
LinesSplit 10 15.499 ms 0.3018 ms 0.5207 ms 1.00 0.00 687.5000 421.8750 140.6250 9119 KB
LinesSubstring 10 4.746 ms 0.0823 ms 0.0808 ms 0.30 0.01 562.5000 281.2500 - 8643.97 KB
LinesMemory 10 3.482 ms 0.0405 ms 0.0379 ms 0.22 0.01 58.5938 27.3438 - 904.15 KB
LinesSplit 15 14.510 ms 0.2732 ms 0.4564 ms 1.00 0.00 671.8750 406.2500 140.6250 9095.12 KB
LinesSubstring 15 4.466 ms 0.0856 ms 0.0800 ms 0.31 0.01 562.5000 281.2500 - 8620.04 KB
LinesMemory 15 3.390 ms 0.0424 ms 0.0354 ms 0.23 0.01 39.0625 15.6250 - 601.28 KB

@ardalis
Copy link
Owner

ardalis commented Aug 22, 2022

For benchmarks I'd think having N vary by a factor of 10 (like you did in your recent video) would be more useful than values of 1/5/10/15, just FYI

{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<LinesBenchmarks>();
Copy link
Owner

Choose a reason for hiding this comment

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

Consider ensuring benchmark methods return identical results

/// Assert.False(lines.MoveNext());
/// </code>
/// </example>
public static IEnumerable<ReadOnlyMemory<char>> Lines(this string text)
Copy link
Owner

Choose a reason for hiding this comment

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

I like that you include a code example in the XML comments!

@ardalis ardalis merged commit 1603a6b into ardalis:main Aug 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants