惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
G
Google Developers Blog
B
Blog
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
The Cloudflare Blog
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
雷峰网
雷峰网
F
Fortinet All Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
A
About on SuperTechFans
量子位
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
H
Help Net Security
Help Net Security
Help Net Security
P
Palo Alto Networks Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Troy Hunt's Blog
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
N
News | PayPal Newsroom
AWS News Blog
AWS News Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
腾讯CDC
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
D
Docker

博客园 - quanben

TECLAST(台电)双系统板tPAD点评 酷比魔方WP10全奔点评 Git Commands Quick Notes Windows Commands and API Linux tricks 全本软件白名单 Quanben Software Whitelist 中文和英文的比较 特征向量到约当标准型 全本论现代中国学人 这才是人工智能的真正显著威胁之一 一些原理 Time-travel Models 哥德尔定理概述 全本一六年一月再论人工智能 如何保存微信的小视频 How to keep WeChat 'Sights' 葱类 Allium 全本论音乐三圣 人类现代史的全本鱼难题 换啤酒问题
an excellent capability of C# language and compiler
quanben · 2015-11-13 · via 博客园 - quanben

Sometimes you want to write code that works for different primitive types, and as C# doesn't support generic type constraints on primitive type hence you can't avoid writing more code, but you may still one way or another minimise the code you have to write and mysteriously end up having to write something like below,

1  public override bool GetValue<T>(int row, int col, out T val)
2 {
3     CacheBlockDouble cache;
4     int r, c;
5     GetCacheAndPoint(row, col, out cache, out r, out c);
6     var dval = cache.Data[r, c];
7     val = (T) (object) dval;
8     return dval != NoDataValue;
9 }

The main concern is on line 7, where a seemingly boxing and unboxing is happening on primitive type dval (which is of double type here) and this is done like this
And we know that T is determined at compile time and is also double, so we hope that the compiler is smart enough to eliminate the unnecessary boxing and interpret that line as below at run time.

It looks like a simple task as everything can be easily evaluated at compile time. But we need proof before we can be sure.
The most reliable way is to examine the IL, however the following code is sufficient.

 1 using System;
 2 
 3 namespace boxing
 4 {
 5     class Program
 6     {
 7         public static T BoxingTest<T>(double v)
 8         {
 9             T result = (T)(object)v;
10             return result;
11         }
12 
13         public static double NonboxingTest(double v)
14         {
15             return v;
16         }
17 
18         static void Main(string[] args)
19         {
20             long countDown = 900000000;
21             const int buffersize = 4096;
22             var buffer = new double[buffersize];
23             var t1 = DateTime.UtcNow;
24             var i = 0;
25             for (; countDown>0; countDown--)
26             {
27                 var t = BoxingTest<double>(i);
28                 //var t = NonboxingTest(countDown);
29                 buffer[i] = t;
30                 i++;
31                 if (i == 4096)
32                 {
33                     i = 0;
34                 }
35             }
36             var t2 = DateTime.UtcNow;
37             Console.WriteLine("finished in {0} secs", (t2-t1).TotalSeconds);
38         }
39     }
40 }

If we compare them, the generic method takes same amount of time as the non-generic counterpart for any iterations. To this point, I'm quite convinced.

And one more thing which is a bit disappointing kind of adds to the confidence: we can't do such thing like below, which will cause a run time exception InvalidCastException: Specifid cast is not valid

1 var d = 1.0;
2 var f = (float)(object)d;

Not even this,

1 var f = 1.0f;
2 var d = (double)(object)f;