RangeExtensions 2.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package RangeExtensions --version 2.1.0                
NuGet\Install-Package RangeExtensions -Version 2.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RangeExtensions" Version="2.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RangeExtensions --version 2.1.0                
#r "nuget: RangeExtensions, 2.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install RangeExtensions as a Cake Addin
#addin nuget:?package=RangeExtensions&version=2.1.0

// Install RangeExtensions as a Cake Tool
#tool nuget:?package=RangeExtensions&version=2.1.0                

RangeExtensions

CI/CD nuget Coverage Status

This package enables the usage of System.Range in foreach expressions and provides extensions to integrate it with LINQ as a faster replacement to Enumerable.Range.

  • Correctness is verified against IEnumerable<int> and Enumerable.Range behavior;
  • Implementation tries its best to make abstractions either zero-cost or reasonably close to that. For critical paths, performance is tuned to be allocation-free and on par with regular for loops

Features

Range enumeration

foreach (var i in ..100) // you can write 0..Length as just ..Length
{
    Console.WriteLine(i);
}

Reverse range enumeration

for (var i = 100 - 1; i >= 0; i--)
{
    Console.WriteLine(i);
}

// Can be written as
foreach (var i in 100..0)
{
    Console.WriteLine(i);
}

Select and Where

var floats = (0..100).Select(i => (float)i);
var odd = (0..100).Where(i => i % 2 != 0);

var randomNumbers = (0..1000)
    .Select(_ => Random.Shared.Next())
    .ToArray();

Collecting to array or list

var numbers = (0..100).ToArray();

Aggregate

var digits = (0..10)
    .Aggregate(new StringBuilder(), (sb, i) => sb.Append(i))
    .ToString();

Assert.Equal("0123456789", digits);

Other LINQ specializations

var enumerable = (..100).AsEnumerable();

var sum = enumerable.Sum();
var count = enumerable.Count;
var average = enumerable.Average();
var firstTen = enumerable.Take(10);
var reversed = enumerable.Reverse();
// and others

Performance

In .NET 7, foreach (var i in 0..Length) has the same performance as for loop. Otherwise, RangeExtensions is 2 to >10 times faster than Enumerable.Range. Using DynamicPGO significantly improves the performance of both.

BenchmarkDotNet=v0.13.2, OS=macOS 13.1 (22C65) [Darwin 22.2.0]
Apple M1 Pro, 1 CPU, 8 logical and 8 physical cores
.NET SDK=8.0.100-alpha.1.22620.11
  [Host]     : .NET 7.0.1 (7.0.122.56804), Arm64 RyuJIT AdvSIMD
  DefaultJob : .NET 7.0.1 (7.0.122.56804), Arm64 RyuJIT AdvSIMD

Job=ShortRun  IterationCount=3  LaunchCount=1  
WarmupCount=3

DOTNET_TieredPGO=1
DOTNET_ReadyToRun=0
Method Length Mean Error Ratio Allocated
For 1 0.0000 ns 0.0000 ns ? -
Range 1 0.6531 ns 0.0051 ns ? -
EnumerableRange 1 8.1135 ns 0.0198 ns ? 40 B
RangeSelect 1 1.1588 ns 0.0048 ns ? -
EnumerableSelect 1 40.7948 ns 0.7697 ns ? 88 B
RangeSelectTwice 1 19.4165 ns 0.0480 ns ? 96 B
EnumerableSelectTwice 1 43.6399 ns 0.0908 ns ? 232 B
RangeWhere 1 1.3954 ns 0.0036 ns ? -
EnumerableWhere 1 26.1945 ns 0.0534 ns ? 96 B
For 100 36.1897 ns 0.0618 ns 1.00 -
Range 100 36.9244 ns 2.0789 ns 1.00 -
EnumerableRange 100 211.4774 ns 0.6430 ns 5.85 40 B
RangeSelect 100 42.6852 ns 0.1689 ns 1.18 -
EnumerableSelect 100 235.7174 ns 0.5161 ns 6.51 88 B
RangeSelectTwice 100 110.1340 ns 0.1667 ns 3.04 96 B
EnumerableSelectTwice 100 298.2976 ns 2.7831 ns 8.22 232 B
RangeWhere 100 56.1455 ns 0.1701 ns 1.55 -
EnumerableWhere 100 249.1264 ns 1.5890 ns 6.89 96 B
For 100000 31,167.5682 ns 37.3266 ns 1.00 -
Range 100000 31,173.8688 ns 13.0666 ns 1.00 -
EnumerableRange 100000 212,925.2827 ns 156.8182 ns 6.83 40 B
RangeSelect 100000 50,086.3342 ns 39.0657 ns 1.61 -
EnumerableSelect 100000 204,113.5813 ns 100.0221 ns 6.55 88 B
RangeSelectTwice 100000 94,302.1444 ns 230.6254 ns 3.02 96 B
EnumerableSelectTwice 100000 203,946.9247 ns 908.5243 ns 6.56 232 B
RangeWhere 100000 47,165.0569 ns 36.7208 ns 1.51 -
EnumerableWhere 100000 209,918.1519 ns 3,298.4418 ns 6.76 96 B
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 is compatible. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETCoreApp 3.1

    • No dependencies.
  • .NETStandard 2.0

  • .NETStandard 2.1

    • No dependencies.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on RangeExtensions:

Repository Stars
U8String/U8String
[work-in-progress] Highly functional and performant UTF-8 string primitive for C#
Version Downloads Last updated
2.1.1 44,610 1/9/2023
2.1.0 306 1/8/2023
2.0.0 315 12/23/2022
1.2.2 712 9/3/2022
1.2.1 392 8/13/2022
1.2.0 380 8/10/2022
1.1.0 384 7/28/2022
1.0.0 405 7/16/2022