Skip to content

Commit 6ce5b33

Browse files
authored
explain possible side effects of using var and implicit casting in the docs (dotnet#1224)
* explain possible side effects of using var and implicit casting in the docs * Update docs/microbenchmark-design-guidelines.md fix typo Co-authored-by: Bill Wert <[email protected]>
1 parent c03ea77 commit 6ce5b33

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

docs/microbenchmark-design-guidelines.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
- [Dead Code Elimination](#Dead-Code-Elimination)
3838
- [Loops](#Loops)
3939
- [Method inlining](#Method-Inlining)
40+
- [Be explicit](#Be-explicit)
4041

4142
## Mindset
4243

@@ -562,3 +563,29 @@ By relying on the BDN mechanism you are going to avoid loop alignment issues. Be
562563
BenchmarkDotNet prevents from inlining the benchmarked method by wrapping it into a delegate (delegates can not be inlined as of today). The cost of delegate invocation is excluded by a separate run for Overhead calculation.
563564

564565
The benchmark methods don't need to have `[MethodImpl(MethodImplOptions.NoInlining)]` attribute applied.
566+
567+
### Be explicit
568+
569+
C# language features like implicit casting and `var` allow us to introduce invisible side effects to the benchmarks.
570+
571+
Sometimes it's just about introducing a small overhead of an implicit cast. In the following example, we cast `Span<byte>` to `ReadOnlySpan<byte>`.
572+
573+
```cs
574+
private byte[] byteArray = new byte[8];
575+
576+
[Benchmark]
577+
public bool TryParseBoolean()
578+
{
579+
var bytes = byteArray.AsSpan(); // bytes is Span<byte>
580+
return Utf8Parser.TryParse(bytes, out bool value, out int bytesConsumed); // TryParse expects ReadOnlySpan<byte>, we introduced implicit cast
581+
}
582+
```
583+
584+
In extreme cases, we might be measuring the performance of a wrong method. In the following example, we measure the performance of `Math.Max` overload that accepts doubles, not floats (this is what we wanted).
585+
586+
```cs
587+
var x = 1.0f; var y = 2.9; // x is float, y is double (missing f)
588+
var result = Math.Max(x, y); // we use double overload because float has implicit cast to double
589+
```
590+
591+
It's our responsibility to ensure that the benchmarks do exactly what we want. This is why using explicit types over `var` is preferred.

0 commit comments

Comments
 (0)