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

Make typeof(T).IsValueType more efficient #12248

Closed
jamesqo opened this issue Feb 16, 2017 · 9 comments
Closed

Make typeof(T).IsValueType more efficient #12248

jamesqo opened this issue Feb 16, 2017 · 9 comments
Labels
Milestone

Comments

@jamesqo
Copy link
Contributor

jamesqo commented Feb 16, 2017

It would be nice to have a cost-free API to check whether a generic type is a class. You can check default(T) != null and be 100% confident something is a struct if that condition is true, but if default(T) == null then it could be a class or a nullable. The only way to tell right now is via reflection, using something like typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>).

I did want to use such an API several times in the past, although I can't recall where. One scenario I can think of though is if you want to treat T as an object if T is a class, but avoid boxing for structs.

Does this sound like a good idea?

Moved from https://github.com/dotnet/corefx/issues/16209

/cc @benaadams @jkotas

@jkotas
Copy link
Member

jkotas commented Feb 16, 2017

The only way to tell right now is via reflection

Why it needs to be this complex? Can't it be just typeof(T).IsValueType ?

@benaadams
Copy link
Member

Counter part of IsReferenceOrContainsReferences<T>() of IsReference<T>()?

@jamesqo
Copy link
Contributor Author

jamesqo commented Feb 16, 2017

typeof(T).IsValueType

@jkotas Well yes, you could use something like default(T) != null || typeof(T).IsValueType to make the check for regular structs fast and still handle nullables (or default(T) == null && typeof(T).IsValueType to detect them), but most code I've seen tends to use what I've written for explicitly detecting nullables. Either way though reflection still needs to be used.

@jamesqo
Copy link
Contributor Author

jamesqo commented Feb 16, 2017

@jkotas As an aside, it looks like the implementation could be changed in Comparer/EqualityComparer to make detecting nullables more efficient... see EqualityComparer and Comparer

@jkotas
Copy link
Member

jkotas commented Feb 16, 2017

So the real problem is that typeof(T).IsValueType is slow. We can either tech the JIT to recognize it as intrinsic; or introduce a new API and tech the JIT to recognize the new API as intrinsic. The first option sounds better to me. Is there a good reason why we would want to introduce a new API for this instead of just make the existing one more efficient?

it looks like the implementation could be changed in Comparer/EqualityComparer

Micro-optimizations in these methods are not interesting. These methods are executed just once; and micro-optimizations won't change how expensive they are.

@jamesqo
Copy link
Contributor Author

jamesqo commented Feb 16, 2017

We can either tech the JIT to recognize it as intrinsic; or introduce a new API and tech the JIT to recognize the new API as intrinsic. The first option sounds better to me. Is there a good reason why we would want to introduce a new API for this instead of just make the existing one more efficient?

How complicated would it be to teach the JIT to recognize existing code as intrinsic? I remember seeing an issue raised by @omariom in coreclr that was dated 2015 about recognizing these kinds of patterns; can't find it now, but I came over it a year later and it was still open.

@jkotas
Copy link
Member

jkotas commented Feb 16, 2017

How complicated would it be to teach the JIT to recognize existing code as intrinsic?

Add new CorInfoIntrinsics enum in inc\corinfo.h; recognize on the VM side; expand it impIntrinsic in the JIT. For example, here is a change that added new intrinsics for Span<T> dotnet/coreclr@0bedde3 (the commit also contains some other unrelated changes).

@omariom
Copy link
Contributor

omariom commented Feb 16, 2017

@jamesqo

I remember seeing an issue raised by @omariom in coreclr that was dated 2015 about recognizing these kinds of patterns;

Make JIT time constants from calls to Type methods and properties

@joperezr
Copy link
Member

Seems like what this issue is about is to make the existing check more efficient, so changing title to match that plus adding the label of enhancement.

@joperezr joperezr changed the title Add an API to check whether a generic type is a class Make typeof(T).IsValueType more efficient Mar 16, 2017
halter73 referenced this issue in dotnet/aspnetcore Jan 17, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
halter73 referenced this issue in dotnet/aspnetcore Jan 18, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
halter73 referenced this issue in dotnet/aspnetcore Feb 22, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
halter73 referenced this issue in dotnet/aspnetcore Feb 22, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
halter73 referenced this issue in dotnet/aspnetcore Feb 23, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
halter73 referenced this issue in dotnet/aspnetcore Feb 25, 2019
I was hoping  typeof(T).IsValueType would get evaluated during JIT
compilation which would allow for dead code elimination, but alas:
https://github.com/dotnet/corefx/issues/16217
@stephentoub stephentoub transferred this issue from dotnet/corefx Mar 12, 2019
@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants