dotnet / dotnet/vblang

[T(Index) Is Nothing] is [CObj(T(Index)) Is Nothing] instead [T(Index) Is Default].

Open
#605 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
328
Forks
71
PR merge metrics
No merged PRs in 30d

Description

```vb
Public Function empty_index(Of T)(Host As T()) As Long
Dim Length = Host.LongLength,
Pos = 0L
Do
If Pos >= Length Then Return -1

'Not work with value type.
If Host(Pos) Is Nothing Then Return Pos

'Because it's compile to this.
If CObj(Host(Pos)) Is Nothing Then Return Pos

'While this work well with value type and reference type.
If Object.Equals(Input, CType(Nothing, T)) Then Return Pos

Pos += 1
Loop
End Function
```

## Why not Object.Equals ?
Simple answer is super cut corner for performance as you see in IL code below.

```
ldarg.0
ldloc.2
conv.i4
ldelem !!T
box !!T
// call bool [System.Runtime]System.Object::Equals(object,object)
brtrue.s IL_0023
```

Instead call `Object.Equals` it use `0` aka `null pointer` compare result so when `brtrue` which is branch on true and true in this case is anything except `0`.

## How to fixed it ?

Just reverse back to use `Object.Equals`.
```vb

Public Function is_default(Of T)(Input As T) As Boolean
Return Object.Equals(Input, CType(Nothing, T))
End Function
```

Or double down it, cut more corner.
```
.method public static bool is_default(!!T Input) cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 2

ldarg.0
ldc.i4.0
ceq
ret
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.