




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、再探C#类与结构体究竟谁快考虑栈变量、栈分配、64位整数、密封类 上次我对C#类与结构体做了一次速度评测(/zyl910/article/details/6788417)。经过一段时间思索,发现还可以进一步探讨第一、栈变量。上次的“硬编码”,是访问类中的静态变量的。若改为访问函数中的栈变量,性能会不会有所提高?第二、栈分配(stackalloc)。既然要测试栈变量,我们还可以顺便测试一下在栈上分配的内存块的访问性能。第三、64位整数。由于32位系统的成功,我们已经习惯了使用32位整数(int)。现在64位系统逐渐普及,我们得为此做好准备。对于指针操作时经常
2、要用到的偏移量增减运算来说,是使用32位整数,还是使用64位整数,或写两套代码?这需要测试后才能决定。第四、密封类(sealed)。听说密封类能提高性能,我们可以测试一下。有两种测试方式,一是为原来的派生类增加sealed关键字,二是专门另外写一个密封类。我决定同时使用这两种方法,分别测试其性能。一、测试代码测试代码如下?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737
3、475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
4、183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
5、283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
6、383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
7、483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace TryPointerCall / / 指针操作接口 / public interface IPointerCall / / 指针操作 /
8、 / 源指针 / 修改后指针 unsafe byte* Ptr(byte* p); #region 非泛型 / / 非泛型 指针操作基类 / public abstract class PointerCall : IPointerCall public abstract unsafe byte* Ptr(byte* p); / / 非泛型 指针操作派生类: 指针+偏移 / public sealed class PointerCallAdd : PointerCall / / 偏移值 / public int Offset = 0; public override unsafe byte* P
9、tr(byte* p) return unchecked(p + Offset); / / 非泛型 指针操作密封类: 指针+偏移 / public sealed class SldPointerCallAdd : IPointerCall / / 偏移值 / public int Offset = 0; public unsafe byte* Ptr(byte* p) return unchecked(p + Offset); / / 非泛型 指针操作结构体: 指针+偏移 / public struct SPointerCallAdd : IPointerCall / / 偏移值 / publ
10、ic int Offset; public unsafe byte* Ptr(byte* p) return unchecked(p + Offset); #endregion #region 泛型 / ! C#不支持将整数类型作为泛型约束 ! /public abstract class GenPointerCall : IPointerCall where T: int, long / / public abstract unsafe byte* Ptr(byte* p); / void d() / / / #endregion #region 全部测试 / / 指针操作的一些常用函数 /
11、 public static class PointerCallTool #if DEBUG private const int CountLoop = 10000000; / 循环次数 #else private const int CountLoop = 200000000; / 循环次数 #endif / / 调用指针操作 / / 具有IPointerCall接口的类型。 / 调用者 / 源指针 / 修改后指针 public static unsafe byte* CallPtr(T ptrcall, byte* p) where T : IPointerCall return ptrc
12、all.Ptr(p); public static unsafe byte* CallClassPtr(T ptrcall, byte* p) where T : PointerCall return ptrcall.Ptr(p); public static unsafe byte* CallRefPtr(ref T ptrcall, byte* p) where T : IPointerCall return ptrcall.Ptr(p); / C#不允许将特定的结构体作为泛型约束。所以对于结构体只能采用上面那个方法,通过IPointerCall接口进行约束,可能会造成性能下降。 /pub
13、lic static unsafe byte* SCallPtr(T ptrcall, byte* p) where T : SPointerCallAdd / / return ptrcall.Ptr(p); / private static int TryIt_Static_Offset; private static unsafe byte* TryIt_Static_Ptr(byte* p) return unchecked(p + TryIt_Static_Offset); / / 执行测试 - 静态调用 / / 文本输出 private static unsafe void Try
14、It_Static(StringBuilder sOut, int CountLoop) TryIt_Static_Offset = 1; / = 性能测试 = byte* p = null; Stopwatch sw = new Stopwatch(); int i; unchecked #region 测试 / 硬编码.栈变量 int iOffset = 1; sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = p + iOffset; sw.Stop(); sOut.AppendLine(string.Format(硬编码.栈
15、变量:t0, sw.ElapsedMilliseconds); / 硬编码.栈分配 int* pOffset = stackalloc int1; pOffset0 = 1; sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = p + pOffset0; sw.Stop(); sOut.AppendLine(string.Format(硬编码.栈分配:t0, sw.ElapsedMilliseconds); / 硬编码.静态 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p
16、 = p + TryIt_Static_Offset; sw.Stop(); sOut.AppendLine(string.Format(硬编码.静态:t0, sw.ElapsedMilliseconds); / 静态调用 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = TryIt_Static_Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(静态调用:t0, sw.ElapsedMilliseconds); #endregion / 测试 private static long
17、 TryIt_Static64_Offset; private static unsafe byte* TryIt_Static64_Ptr(byte* p) return unchecked(p + TryIt_Static64_Offset); / / 执行测试 - 静态调用 / / 文本输出 private static unsafe void TryIt_Static64(StringBuilder sOut, int CountLoop) TryIt_Static64_Offset = 1; / = 性能测试 = byte* p = null; Stopwatch sw = new
18、Stopwatch(); int i; unchecked #region 测试 / 硬编码.栈变量 long iOffset = 1; sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = p + iOffset; sw.Stop(); sOut.AppendLine(string.Format(64硬编码.栈变量:t0, sw.ElapsedMilliseconds); / 硬编码.栈分配 long* pOffset = stackalloc long1; pOffset0 = 1; sw.Reset(); sw.Start();
19、 for (i = 0; i CountLoop; +i) p = p + pOffset0; sw.Stop(); sOut.AppendLine(string.Format(64硬编码.栈分配:t0, sw.ElapsedMilliseconds); / 硬编码.静态 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = p + TryIt_Static64_Offset; sw.Stop(); sOut.AppendLine(string.Format(64硬编码.静态:t0, sw.ElapsedMilliseconds);
20、/ 静态调用 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = TryIt_Static64_Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(64静态调用:t0, sw.ElapsedMilliseconds); #endregion / 测试 / / 执行测试 - 非泛型 / / 文本输出 private static unsafe void TryIt_NoGen(StringBuilder sOut, int CountLoop) / 创建 PointerCallAdd pc
21、a = new PointerCallAdd(); SldPointerCallAdd dpca = new SldPointerCallAdd(); SPointerCallAdd spca; pca.Offset = 1; spca.Offset = 1; / 转型 PointerCall pca_base = pca; IPointerCall pca_itf = pca; IPointerCall dpca_itf = dpca; IPointerCall spca_itf = spca; / = 性能测试 = byte* p = null; Stopwatch sw = new St
22、opwatch(); int i; unchecked #region 调用 #region 直接调用 / 调用派生类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = pca.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用派生类:t0, sw.ElapsedMilliseconds); / 调用密封类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = dpca.Ptr(p); sw.Stop(); sOut.A
23、ppendLine(string.Format(调用密封类:t0, sw.ElapsedMilliseconds); / 调用结构体 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = spca.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用结构体:t0, sw.ElapsedMilliseconds); #endregion / 直接调用 #region 间接调用 / 调用基类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop;
24、+i) p = pca_base.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用基类:t0, sw.ElapsedMilliseconds); / 调用派生类的接口 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = pca_itf.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用派生类的接口:t0, sw.ElapsedMilliseconds); / 调用密封类的接口 sw.Reset(); sw.Start(); fo
25、r (i = 0; i CountLoop; +i) p = dpca_itf.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用密封类的接口:t0, sw.ElapsedMilliseconds); / 调用结构体的接口 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = spca_itf.Ptr(p); sw.Stop(); sOut.AppendLine(string.Format(调用结构体的接口:t0, sw.ElapsedMilliseconds); #endregio
26、n / 间接调用 #endregion / 调用 #region 泛型调用 #region 泛型基类约束 / 基类泛型调用派生类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallClassPtr(pca, p); sw.Stop(); sOut.AppendLine(string.Format(基类泛型调用派生类:t0, sw.ElapsedMilliseconds); / 基类泛型调用基类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallClas
27、sPtr(pca_base, p); sw.Stop(); sOut.AppendLine(string.Format(基类泛型调用基类:t0, sw.ElapsedMilliseconds); #endregion / 泛型基类约束 #region 泛型接口约束 - 直接调用 / 接口泛型调用派生类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallPtr(pca, p); sw.Stop(); sOut.AppendLine(string.Format(接口泛型调用派生类:t0, sw.ElapsedMilliseco
28、nds); / 接口泛型调用密封类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallPtr(dpca, p); sw.Stop(); sOut.AppendLine(string.Format(接口泛型调用密封类:t0, sw.ElapsedMilliseconds); / 接口泛型调用结构体 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallPtr(spca, p); sw.Stop(); sOut.AppendLine(string.Format
29、(接口泛型调用结构体:t0, sw.ElapsedMilliseconds); / 接口泛型调用结构体引用 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallRefPtr(ref spca, p); sw.Stop(); sOut.AppendLine(string.Format(接口泛型调用结构体引用:t0, sw.ElapsedMilliseconds); #endregion / 直接调用 #region 间接调用 / 接口泛型调用基类 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallPtr(pca_base, p); sw.Stop(); sOut.AppendLine(string.Format(接口泛型调用基类:t0, sw.ElapsedMilliseconds); / 接口泛型调用派生类的接口 sw.Reset(); sw.Start(); for (i = 0; i CountLoop; +i) p = CallPtr(pca_itf, p); sw.Stop(); sOut.AppendLine(string.Format(接口泛型调用派生类的接口:t0, sw.E
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025版中外合作经营合同范本下载
- 2025仓库租赁合同的书写格式及注意事项
- 输油工(中级投运)练习卷含答案
- 土建施工-单选判断复习测试题
- 2025至2030中国桥梁钢结构行业市场竞争格局及有效策略与实施路径评估报告
- 护理学教案课件设计与实施要点
- 产科个案护理
- 护理工作模式与管理体系
- 第四脑室护理要点
- 朝阳2025年朝阳市消防救援支队政府专职消防员招聘39人笔试历年参考题库附带答案详解
- 《中式美食鉴赏》课件
- 民航旅客运输试题及答案
- 安全用电宣传课件初中
- 国开电大软件工程形考作业3参考答案 (一)
- 2025年-天津市安全员-B证考试题库附答案
- 2025年铁路列车员(中级)职业技能鉴定参考试题库-上(单选题)
- 游泳馆安全知识培训课件
- 2025年辽宁省抚顺市顺城区中考一模历史试题(原卷版+解析版)
- 第5课 弘扬劳动精神、劳模精神、工匠精神(教学设计) -【中职专用】中职思想政治《职业道德与法治》同步教学教学设计(高教版2023·基础模块)
- 行政费用管理控制办法及规定
- 建筑行业防震减灾技术培训计划
评论
0/150
提交评论