Skip to content

Commit 042680b

Browse files
committed
Mutation testing with stryker
1 parent 6c9825e commit 042680b

File tree

11 files changed

+185
-60
lines changed

11 files changed

+185
-60
lines changed

.config/dotnet-tools.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"dotnet-stryker": {
6+
"version": "4.5.1",
7+
"commands": [
8+
"dotnet-stryker"
9+
],
10+
"rollForward": false
11+
},
12+
"csharpier": {
13+
"version": "1.0.1",
14+
"commands": [
15+
"csharpier"
16+
],
17+
"rollForward": false
18+
}
19+
}
20+
}

Directory.Build.props

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
<AnalysisLevel>latest</AnalysisLevel>
99
<Features>strict</Features>
1010
<ImplicitUsings>enable</ImplicitUsings>
11-
1211
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1312
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
1413
<PackageProjectUrl>https://github.com/martinothamar/FastLazy</PackageProjectUrl>
@@ -18,9 +17,8 @@
1817
<Authors>Martin Othamar</Authors>
1918
<Copyright>Copyright 2022 Martin Othamar</Copyright>
2019
</PropertyGroup>
21-
2220
<ItemGroup>
23-
<PackageReference Include="CSharpier.MsBuild" Version="0.16.0">
21+
<PackageReference Include="CSharpier.MsBuild" Version="1.0.1">
2422
<PrivateAssets>all</PrivateAssets>
2523
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
2624
</PackageReference>

FastLazy.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_files", "_files", "{41092E
2222
global.json = global.json
2323
EndProjectSection
2424
EndProject
25+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{4DB2B86E-7239-408A-A53E-8324EB5AAC03}"
26+
EndProject
27+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastLazy.Benchmarks", "benchmarks\FastLazy.Benchmarks\FastLazy.Benchmarks.csproj", "{EC901FF0-D16E-46CE-A30C-E54D758BACFC}"
28+
EndProject
2529
Global
2630
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2731
Debug|Any CPU = Debug|Any CPU
@@ -36,13 +40,18 @@ Global
3640
{40AF2B0E-EE6B-4474-B1CC-E4A9AF5ECA87}.Debug|Any CPU.Build.0 = Debug|Any CPU
3741
{40AF2B0E-EE6B-4474-B1CC-E4A9AF5ECA87}.Release|Any CPU.ActiveCfg = Release|Any CPU
3842
{40AF2B0E-EE6B-4474-B1CC-E4A9AF5ECA87}.Release|Any CPU.Build.0 = Release|Any CPU
43+
{EC901FF0-D16E-46CE-A30C-E54D758BACFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44+
{EC901FF0-D16E-46CE-A30C-E54D758BACFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
45+
{EC901FF0-D16E-46CE-A30C-E54D758BACFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
46+
{EC901FF0-D16E-46CE-A30C-E54D758BACFC}.Release|Any CPU.Build.0 = Release|Any CPU
3947
EndGlobalSection
4048
GlobalSection(SolutionProperties) = preSolution
4149
HideSolutionNode = FALSE
4250
EndGlobalSection
4351
GlobalSection(NestedProjects) = preSolution
4452
{ABA612E2-0813-4116-B9DC-4566DD1CF861} = {BE71197F-A2B5-4C76-BED1-C8971D18AE90}
4553
{40AF2B0E-EE6B-4474-B1CC-E4A9AF5ECA87} = {DA7BBA71-8F4C-4D94-A10C-DBB9BA79C553}
54+
{EC901FF0-D16E-46CE-A30C-E54D758BACFC} = {4DB2B86E-7239-408A-A53E-8324EB5AAC03}
4655
EndGlobalSection
4756
GlobalSection(ExtensibilityGlobals) = postSolution
4857
SolutionGuid = {81A7EF20-CED6-4543-A514-E311555B849E}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<LangVersion>latest</LangVersion>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<DebugType>pdbonly</DebugType>
7+
<DebugSymbols>true</DebugSymbols>
8+
<GenerateDocumentationFile>false</GenerateDocumentationFile>
9+
<Nullable>disable</Nullable>
10+
</PropertyGroup>
11+
<ItemGroup>
12+
<Using Include="BenchmarkDotNet.Attributes" />
13+
<Using Include="BenchmarkDotNet.Order" />
14+
<Using Include="BenchmarkDotNet.Configs" />
15+
<Using Include="BenchmarkDotNet.Jobs" />
16+
<Using Include="BenchmarkDotNet.Diagnosers" />
17+
<Using Include="BenchmarkDotNet.Loggers" />
18+
<Using Include="BenchmarkDotNet.Diagnostics.Windows.Configs" />
19+
</ItemGroup>
20+
<ItemGroup>
21+
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
22+
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.14.0" />
23+
</ItemGroup>
24+
<ItemGroup>
25+
<ProjectReference Include="..\..\src\FastLazy\FastLazy.csproj" />
26+
</ItemGroup>
27+
</Project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace FastLazy.Benchmarks;
2+
3+
[MemoryDiagnoser]
4+
[Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)]
5+
[RankColumn]
6+
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
7+
[DisassemblyDiagnoser]
8+
//[InliningDiagnoser(logFailuresOnly: true, allowedNamespaces: new[] { "Mediator" })]
9+
public class FastLazyValueBenchmarks
10+
{
11+
private Lazy<long> _lazy;
12+
private FastLazyValue<long, long> _fastLazy;
13+
14+
[GlobalSetup]
15+
public void Setup()
16+
{
17+
_lazy = new Lazy<long>(() => 1);
18+
_fastLazy = new FastLazyValue<long, long>(_ => 1, 0);
19+
}
20+
21+
[Benchmark]
22+
public long Lazy_Value() => _lazy.Value;
23+
24+
[Benchmark]
25+
public long FastLazy_Value() => _fastLazy.Value;
26+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using BenchmarkDotNet.Running;
2+
3+
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "6.0.101",
3+
"version": "8.0.408",
44
"rollForward": "latestFeature"
55
}
66
}

src/FastLazy/FastLazy.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
32
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
3+
<TargetFramework>net8.0</TargetFramework>
54
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
65
</PropertyGroup>
7-
86
<ItemGroup>
97
<InternalsVisibleTo Include="FastLazy.Tests" />
108
</ItemGroup>
11-
129
</Project>

src/FastLazy/FastLazyValue.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,29 @@ namespace FastLazy;
77
/// Lock-free and threadsafe code using atomics.
88
/// </summary>
99
/// <typeparam name="T">struct type</typeparam>
10-
public struct FastLazyValue<T> where T : struct
10+
/// <typeparam name="TArg">Argument type</typeparam>
11+
public struct FastLazyValue<T, TArg>
12+
where T : struct
1113
{
1214
internal const long INVALID = -1;
1315
internal const long UNITIALIZED = 0;
1416
internal const long INITIALIZING = 1;
1517
internal const long INITIALIZED = 2;
1618
internal const long CACHED = 3;
1719

18-
private readonly Func<T> _generator;
19-
private long _state;
20-
private T _value;
20+
internal readonly Func<TArg, T> _generator;
21+
internal long _state;
22+
internal T _value;
23+
internal TArg _arg;
24+
25+
private unsafe ref T _valueRef => ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _value));
2126

2227
/// <summary>
2328
/// Wether or not the value of T has been initialized
2429
/// </summary>
2530
public readonly bool IsValueCreated => _state == INITIALIZED;
2631

27-
unsafe private ref readonly T _valueRef => ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _value));
28-
29-
unsafe private ref T _valueRefAndAddress(out long address)
32+
private unsafe ref T _valueRefAndAddress(out long address)
3033
{
3134
var ptr = Unsafe.AsPointer(ref _value);
3235
address = (long)ptr;
@@ -48,7 +51,7 @@ public T Value
4851
}
4952
}
5053

51-
private T ValueSlow
54+
internal T ValueSlow
5255
{
5356
[MethodImpl(MethodImplOptions.NoInlining)]
5457
get
@@ -76,7 +79,7 @@ public ref readonly T ValueRef
7679
}
7780
}
7881

79-
private ref readonly T ValueRefSlow
82+
internal ref T ValueRefSlow
8083
{
8184
[MethodImpl(MethodImplOptions.NoInlining)]
8285
get
@@ -97,14 +100,14 @@ internal ref T GetValueInstrumented(out long previousState, out long address)
97100
}
98101

99102
[MethodImpl(MethodImplOptions.NoInlining)]
100-
private ref T GetValueInstrumentedSlow(out long previousState, out long address)
103+
internal ref T GetValueInstrumentedSlow(out long previousState, out long address)
101104
{
102105
TryInit(out previousState);
103106
return ref _valueRefAndAddress(out address);
104107
}
105108

106109
[MethodImpl(MethodImplOptions.AggressiveInlining)]
107-
private void TryInit(out long previousState)
110+
private unsafe void TryInit(out long previousState)
108111
{
109112
previousState = Interlocked.CompareExchange(ref _state, INITIALIZING, UNITIALIZED);
110113
switch (previousState)
@@ -119,7 +122,7 @@ private void TryInit(out long previousState)
119122
spinWait.SpinOnce();
120123
return;
121124
case UNITIALIZED:
122-
_value = _generator();
125+
_value = _generator(_arg);
123126
Interlocked.Exchange(ref _state, INITIALIZED);
124127
return;
125128
}
@@ -129,11 +132,13 @@ private void TryInit(out long previousState)
129132
/// Constructs the lazy instance.
130133
/// </summary>
131134
/// <param name="generator">Generator function for the instance of T</param>
132-
public FastLazyValue(Func<T> generator)
135+
/// <param name="arg">Argument to the generator function</param>
136+
public FastLazyValue(Func<TArg, T> generator, TArg arg)
133137
{
134138
_generator = generator;
135139
_state = UNITIALIZED;
136140
_value = default;
141+
_arg = arg;
137142
}
138143

139144
/// <summary>
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
2-
1+
<Project Sdk="Microsoft.NET.Sdk">
32
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
5-
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
65
</PropertyGroup>
7-
86
<PropertyGroup>
97
<NoWarn>$(NoWarn);1591</NoWarn>
108
</PropertyGroup>
11-
129
<ItemGroup>
13-
<Using Include="FluentAssertions" />
10+
<PackageReference Include="coverlet.collector" Version="6.0.4">
11+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
12+
<PrivateAssets>all</PrivateAssets>
13+
</PackageReference>
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
15+
<PackageReference Include="xunit" Version="2.9.3" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
<PrivateAssets>all</PrivateAssets>
19+
</PackageReference>
1420
</ItemGroup>
15-
16-
<ItemGroup>
17-
<PackageReference Include="Fixie.TestAdapter" Version="3.2.0" />
18-
<PackageReference Include="FluentAssertions" Version="6.6.0" />
19-
</ItemGroup>
20-
2121
<ItemGroup>
2222
<ProjectReference Include="..\..\src\FastLazy\FastLazy.csproj" />
2323
</ItemGroup>
24-
2524
</Project>

0 commit comments

Comments
 (0)