Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need an efficient helper to check if an instance of T is a default(T) #20240

Open
VSadov opened this issue Feb 16, 2017 · 5 comments
Open

Need an efficient helper to check if an instance of T is a default(T) #20240

VSadov opened this issue Feb 16, 2017 · 5 comments
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Runtime
Milestone

Comments

@VSadov
Copy link
Member

VSadov commented Feb 16, 2017

The need arises once in a while to check if a value at hand is not initialized.

See for example comments on dotnet/corefx#16122 (comment)

Also, If/when parameterless constructors for structs are introduced, the need for IsDefault check could become more apparent.

@VSadov
Copy link
Member Author

VSadov commented Feb 16, 2017

CC @jkotas

@jamesqo
Copy link
Contributor

jamesqo commented Feb 16, 2017

Yes, definitely, this would be awesome. A cost-free API for checking whether some generic type is a class (and not a nullable) would be nice too, if it can be implemented straightforwardly.

@jkotas
Copy link
Member

jkotas commented Feb 16, 2017

The need arises once in a while to check if a value at hand is not initialized.

Do you have more examples where this would be needed? It is not a rocket science to write such helper - take address of the value and its size, and check whether it is all zeros (using unsafe code, potentially with the usual loop unrolling, etc.).

A cost-free API for checking whether some generic type is a class (and not a nullable) would be nice too

Agree. It should be separate issue.

@JonHanna
Copy link
Contributor

If it could work on a boxed value, I'd use it in System.Linq.Expressions.Compiler.ILGen.TryEmitConstant so that any value type not already handled could have a constant that happened to be the default emitted the same way default expressions are. As is one would have to create a default value of the given type through reflection before using RuntimeHelpers.Equals() and that allocation just to test is probably not worth it.

@sakno
Copy link
Contributor

sakno commented Aug 2, 2019

I've implemented prototype of such method as a part of my library so the code can be reused. Source code is here and the public method is here.
I did that according with the following assumptions:

  1. The value to be checked is passed by value in the method so I have guarantees that stack-allocated value will not be moved by GC event if value type has fields of reference types
  2. sizeof IL instruction always can be replaced by constant value at JIT compilation. All checks in my implementation based on assumption that JIT removes dead code because all subsequent checks based on the value returned by sizeof.
  3. The code contains a few optimized paths for data types of size 1, 2, 4 and 8. In this case JIT replaces my code with simple ceq instruction.
  4. For large structs (more than 8 bytes) I use memory aligned zero check accelerated by Vector if underlying hardware supports it

Additionally, I have BitwiseEquals method that works in similar way and it demonstrates good performance.

However, I used inline IL for implementation to keep the full control over generated code. But I'm sure that the same behavior can be achieved using S.R.CS.Unsafe class

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@joperezr joperezr removed the untriaged New issue has not been triaged by the area owner label Jul 6, 2020
@joperezr joperezr modified the milestones: 5.0.0, Future Jul 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Runtime
Projects
None yet
Development

No branches or pull requests

8 participants