Skip to content

Commit d6addb9

Browse files
committed
Merge branch 'valuetask-nongeneric-inprocess' into temp
2 parents f90d2a4 + dbe28c6 commit d6addb9

File tree

5 files changed

+265
-25
lines changed

5 files changed

+265
-25
lines changed

src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ private static BenchmarkAction CreateCore(
3232
if (resultType == typeof(Task))
3333
return new BenchmarkActionTask(resultInstance, targetMethod, unrollFactor);
3434

35+
if (resultType == typeof(ValueTask))
36+
return new BenchmarkActionValueTask(resultInstance, targetMethod, unrollFactor);
37+
3538
if (resultType.GetTypeInfo().IsGenericType)
3639
{
3740
var genericType = resultType.GetGenericTypeDefinition();

src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Implementations.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,45 @@ private void InvokeMultipleHardcoded(long repeatCount)
148148
public override object LastRunResult => result;
149149
}
150150

151+
internal class BenchmarkActionValueTask : BenchmarkActionBase
152+
{
153+
private readonly Func<ValueTask> startTaskCallback;
154+
private readonly Action callback;
155+
private readonly Action unrolledCallback;
156+
157+
public BenchmarkActionValueTask(object instance, MethodInfo method, int unrollFactor)
158+
{
159+
bool isIdle = method == null;
160+
if (!isIdle)
161+
{
162+
startTaskCallback = CreateWorkload<Func<ValueTask>>(instance, method);
163+
callback = ExecuteBlocking;
164+
}
165+
else
166+
{
167+
callback = Overhead;
168+
}
169+
170+
InvokeSingle = callback;
171+
172+
unrolledCallback = Unroll(callback, unrollFactor);
173+
InvokeMultiple = InvokeMultipleHardcoded;
174+
175+
}
176+
177+
// must be kept in sync with VoidDeclarationsProvider.IdleImplementation
178+
private void Overhead() { }
179+
180+
// must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate
181+
private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());
182+
183+
private void InvokeMultipleHardcoded(long repeatCount)
184+
{
185+
for (long i = 0; i < repeatCount; i++)
186+
unrolledCallback();
187+
}
188+
}
189+
151190
internal class BenchmarkActionValueTask<T> : BenchmarkActionBase
152191
{
153192
private readonly Func<ValueTask<T>> startTaskCallback;

src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ private static BenchmarkAction CreateCore(
3434
if (resultType == typeof(Task))
3535
return new BenchmarkActionTask(resultInstance, targetMethod, codegenMode, unrollFactor);
3636

37+
if (resultType == typeof(ValueTask))
38+
return new BenchmarkActionValueTask(resultInstance, targetMethod, codegenMode, unrollFactor);
39+
3740
if (resultType.GetTypeInfo().IsGenericType)
3841
{
3942
var genericType = resultType.GetGenericTypeDefinition();

src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Implementations.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,51 @@ private void InvokeMultipleHardcoded(long repeatCount)
175175
public override object LastRunResult => result;
176176
}
177177

178+
internal class BenchmarkActionValueTask : BenchmarkActionBase
179+
{
180+
private readonly Func<ValueTask> startTaskCallback;
181+
private readonly Action callback;
182+
private readonly Action unrolledCallback;
183+
184+
public BenchmarkActionValueTask(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
185+
{
186+
bool isIdle = method == null;
187+
if (!isIdle)
188+
{
189+
startTaskCallback = CreateWorkload<Func<ValueTask>>(instance, method);
190+
callback = ExecuteBlocking;
191+
}
192+
else
193+
{
194+
callback = Overhead;
195+
}
196+
197+
InvokeSingle = callback;
198+
199+
if (UseFallbackCode(codegenMode, unrollFactor))
200+
{
201+
unrolledCallback = Unroll(callback, unrollFactor);
202+
InvokeMultiple = InvokeMultipleHardcoded;
203+
}
204+
else
205+
{
206+
InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), null, unrollFactor);
207+
}
208+
}
209+
210+
// must be kept in sync with VoidDeclarationsProvider.IdleImplementation
211+
private void Overhead() { }
212+
213+
// must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate
214+
private void ExecuteBlocking() => Helpers.AwaitHelper.GetResult(startTaskCallback.Invoke());
215+
216+
private void InvokeMultipleHardcoded(long repeatCount)
217+
{
218+
for (long i = 0; i < repeatCount; i++)
219+
unrolledCallback();
220+
}
221+
}
222+
178223
internal class BenchmarkActionValueTask<T> : BenchmarkActionBase
179224
{
180225
private readonly Func<ValueTask<T>> startTaskCallback;

0 commit comments

Comments
 (0)