前景提要:

  编写程序时,也许你不经意间,就不知不觉的定义了错误的类型,从而发生了额外的性能消耗,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环、网络程序(不断请求处理的)等这些时候,减少了不必要额外的消耗,使优化程序提高效率的一种途径。不仅跬步,无以至千里,不积小流,无以至江河。优化从点点滴滴做起。

一、问题抛出:

  大家先看这么一段定义

  class ReserveData 
  {
    public string ReserveId;  
    public string patient_id;
    public string patient_name; 
    public string queue_type_id;
    public string source_code;
    public string IsCall;  
    public string date;
    public string start_time;
    public string end_time;
    public string reserve_timespan_id;
}

  这是真实的摘自同事代码,先不说命名规则,Pascal、骆驼命名,(其中我们自己定义来自数据库使用骆驼,自定义变量使用Pascal)

  这段代码主要用途是向前台页面序列化ReserveData的List的json。

  以前我从没感觉类型定义会是什么问题,这个谁会出什么问题呢,可是有人真的就这么干,最后还不以为然。

二、问题解析一——字段类型定义

  在您这么定义的时候,您觉得可能这样定义并没有什么,甚至会说:“我都工作,两三年了,别对我指手画脚的”。

  一共工作过两家公司,均有一些工作两三年的同事,这样使用。偶的神啊!

  2.1 不同层面分析

    2.1.1 从程序员角度理解

      从程序员角度,我真的理解不了,你要表达的意思,明明是bool,一个true,false的意思,你变成string,datetime,也定义成string。  我去问他们,来了一句,“那怎么了,又不影响使用,你别纠结这些问题了,想想流程”。我不知该说什么。

    2.1.2 从机器CLR去理解

      确实,我够智能,你怎么着,我都给你正常编译、执行,但是正常干活已经够累的了,怎么还给我找事,告诉你,消耗cpu,内存过多,我就给你宕机去。

    2.1.3 实际使用中的我

       苦逼的我在前台js接收json时,针对bool怎么也是解析不出来,各种怪现象,看了源代码,有种想抽她的冲动,bool类型返回的是string类型的“True”,int32返回的也变成string类型数值,datetime类型也不是预想中的毫秒值,变成了string(2014/05/30 09:00:00),你说我能不抽她吗??

    2.1.4 性能分析

      现在咱们,就分析一下这段类型定义。

        在这其中 ReserveId 其实是 int32
        IsCall 其实是 bool
        start_time、end_time 其实是 Datetime
        patient_name 是 String 其他的也可能有别的类型,

      这里主要指出的不按真实情况,定义应有的类型,接收应有的数据,而自以为事的胡乱定义。第一、原本是值类型的,如果您定义成了string引用类型,可能造成不必要的装箱,性能损失。(补充一句,谢谢网友“ 冰麟轻武”提醒,这里使用类接收或者承载数据库数据之后,需要对其进行操作的,string 类型的Datetime,需要使用类型装换,同时还有一些其他的操作,“可能”会造成装箱,拆箱。可能使用Convert、(Int)强转、int.Parse()等类似 值类型→引用类型,引用类型→值类型) 第二、原本是引用类型的,如果您定义成了Int32、Boolean等值类型,可能直接就会有语法错误。第三,增加程序员之间的配合难度。以及会是程序中出现各种怪问题。

      装箱是很消耗性能的一种操作,这里不再详述:可参看:C# 程序性能提升篇-1、装箱和拆箱,枚举的ToString浅析

      实际事例:像这种List<ReserveData>,可能会有多条,每次都会进行装箱,就按本例使用示例分析一下性能问题(以实际现状分析,本人从事医疗辅助软件开发)
        (说明一下,一般医院给这种医疗辅助软件的服务器,就那么一台(四核八线程,4G内存),更有可能者,只给你一个虚拟机。web和DB在一台服务器,这还不止一个医疗辅助软件系统,还有其他的多媒体展示,或者其他医院系统)
        示例:某医院有一百个终端屏幕(小医院的点数,大医院会上千),其实就是请求客户端。每个终端屏幕每隔60s请求一次(这一般是最小的),甚至有的医院要求5s刷新,每次列表有10个患者。ok,这是实际情景
          咱们数学计算一下,预定义量,假设每次装箱耗时1ms、内存消耗1k,cpu使用0.001%
                (以上使用10个字段,8个可能发生装箱,每次list按10个计算)  
          粗略计算一下100个同时请求的即时消耗
            时间 100个屏幕*10个患者*8个装箱字段*1s时间*1ms额外消耗==8000ms =8s
            内存 100个屏幕*10个患者*8个装箱字段*1s时间*1K 额外消耗==8000K  =8M
            CPU  100个屏幕*10个患者*8个装箱字段*1s时间*0.001%额外消耗==8%

          这还仅仅是系统中的一角,如果有更多的这种额外消耗,那么程序就死定了

      综上所述,额外消耗(可能所有的基数并不准确,但是消耗是一定的,你懒了,机器多干活了,必然会有多的消耗(能量守恒定律码)),只不过是微乎其微的消耗;
        桌面程序,请求数少,可以忽略不计;
        局域网程序,像我们这种,频繁多请求,在服务器cpu、内存控制下,就得考虑额外消耗;
        互联网则更需要考虑,轻则上千,重则千万级别,再深了更别说了。这种额外的消耗(完全可以避免的消耗),并不在正常消耗之内的消耗,可能就是造成您的cpu,内存,居高不小的主要原因。

三、问题解析二——class和struct

  3.1概念简述

      3.1.1 不用多说,class 是引用类型,struct是值类型

      3.1.2 补充一句,引用类型开辟内存栈指针,内存堆存放数据,具体内存等资源释放由CLR的GC处理,偏重型;   值类型,存放于内存栈中,在作用域结束释放,轻型

      3.1.3 class与struct差不多一样,struct 是C、C++旧时代的产物,class才是王道,才是面向对象中使用的。C#中之所以有struct 是为了兼容C、C++程序员才过度的产物。估计很多您search过,都是这个答案吧。回忆,看过的教程、百度、google,博客园,甚至曾经的自己,都是这种想法。

    3.2什么时候使用类、什么时候使用struct  

      google一下就很多了,不在深入抄袭,但是看到以上类似3.1.3的话您就别看了,我给您补充一下:

        1.对于轻量级的数据组,类似上面的就是一些字段、属性的序列化,没有进一步抽象,继承的需求可以考虑使用Struct;
        2.struct  类型是一种值类型,通常用来封装小型相关变量组(MSDN:http://msdn.microsoft.com/zh-cn/library/ah19swz4.aspx)  
        3..结构用于封装由相关字段组成的组。因为结构是值类型,所以它们的分配效率要比类略高些(来自MSDN:http://msdn.microsoft.com/zh-cn/library/ms228600(v=vs.90).aspx)  
        4.结构还可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型(MSDN:http://msdn.microsoft.com/zh-cn/library/ah19swz4.aspx)  
        5.类是反映现实事物的一种抽象,而结构体的作用只是一种包含了具体不同类别数据的一种包装,结构体不具备类的继承多态特性  综上所述,您也知道了吧,还是那句话,什么时候什么场景该用什么类型就要用什么类型。

小结:  
    1.字段类型的定义,一定要符合实际,不要随便胡乱定义。要不然可能造成的后果,别人不理解您的程序,机器损失巨大性能。  
    2.class,struct,合适场景用合适的定义,不经意间提升你程序的性能。  
    3.程序进步、优雅,技能同时也会再进步,难道money还会少吗??

C# 程序性能提升篇-2、类型(字段类型、class和struct)的错误定义所影响性能浅析的更多相关文章

  1. C# 程序性能提升篇-1、装箱和拆箱,枚举的ToString浅析

    前景提要: 编写程序时,也许你不经意间,就不知不觉的使程序代码,发生了装箱和拆箱,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候,减少装箱和拆 ...

  2. Android中SQLite查询date类型字段出现有返回但是为错误值的情况

    出现该情况的原因是因为查询精度与数据库中存储精度不相同造成的,例如,查询精度为 YYYY-MM-DD 但是存储精度为 YYYY-MM-DD HH:MM:SS,就会出现该错误. 更改查询精度为YYYY- ...

  3. 【mysql的设计与优化专题(3)】字段类型与合理的选择字段类型

    本篇博客稍微有点长,它实际上包括两个内容:一是mysql字段类型的介绍,二是在mysql建表过程中是如何正确选择这些字段类型; 字段类型 数值 MySQL 的数值数据类型可以大致划分为两个类别,一个是 ...

  4. mysql数据库字段类型的选择原则

    原文链接:http://blog.csdn.net/u013412790/article/details/51615407 数据库类型的选择对数据库的性能影响很大 1 . 数据类型会影响存储空间的开销 ...

  5. ORACLE插入DATE类型字段

    1 怎样在ORACLE中输入DATE类型的字段 insert into table_name (date_column) values(to_date('2006-06-04','yyyy-mm-dd ...

  6. SolidWorks 2020新增功能之性能提升

    SolidWorks解决方案组合的新功能和增强功能将帮助您最大程度地提高设计和制造资源的生产率,同时使您能够更快地交付创新产品.现在我们很激动地告诉你,三维设计SolidWorks  3D CAD 2 ...

  7. Solr字段类型field type的定义

    摘要: Solr的字段类型定义了Solr如何解析字段数据并将数据检索出来,了解Solr的字段类型定义有助于更好的配置与使用Solr. 字段类型的定义 字段类型的定义主要包含如下四个方面的信息: 名称 ...

  8. mysql配置与存储引擎与字段类型与约束条件

    目录 字符编码与配置文件 存储引擎 创建表的完整语法 字段类型 整型 浮点型 字符类型 数字的含义 枚举与集合 日期类型 约束条件 字符编码与配置文件 在MySQL5.X系列中,显示的字符编码有多种, ...

  9. 1.4.2 solr字段类型--(1.4.2.6)使用外部文件和程序

    1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...

随机推荐

  1. poj 1287 Networking【最小生成树prime】

    Networking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7321   Accepted: 3977 Descri ...

  2. jQuery选择器总结 转

    jQuery选择器总结 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 3 ...

  3. Spring与Ibatis整合入门

    Ibatis作为一个将java对象与sql中的数据进行映射的工具,可以将一个应用中常用的sql操作抽象为模版,在应用后续与数据库的交互中,将输入sql语句简化为更改一部分参数. ibatis整合到sp ...

  4. java基础之 IO流

    javaIO流   IO流 : (input  output) 输入输出流 :输入 :将文件读到内存中 输出:将文件从内存输出到其他地方.   IO技术的作用:主要就是解决设备和设备之间的数据传输问题 ...

  5. hdu 2546 饭卡(DP)

    很久以前做过这道题,晚上睡不着,看见nyist加了一个DP的比赛,就进来打个酱油. 这道题的点睛之笔是将最大值记录下来,然后将其值改为0.之后就是普通的背包了. #include<stdio.h ...

  6. Eclipse如何生成带有自定tag的Java Doc

    1. 选择要生成Java Doc的工程,单击鼠标右键,在弹出菜单中选择[Export],会弹出以下对话框: 2. 选择[Java]--->[Javadoc],点击[Next]按钮,弹出以下对话框 ...

  7. const char*, char const* and char *const 分类: C/C++ OpenCV 2014-11-08 18:10 114人阅读 评论(0) 收藏

    const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目.  事实上这个概念谁都有只是三种声明方式非常相似很容易记混.  Bjarne在他的 ...

  8. [Javascript] Creating an Immutable Object Graph with Immutable.js Map()

    Learn how to create an Immutable.Map() through plain Javascript object construction and also via arr ...

  9. 使用Partitioner实现输出到多个文件

    1.需求 按学生的年龄段,将数据输出到不同的文件.这里我们分为三个年龄段:小于等于20岁.大于20岁小于等于50岁和大于50岁 2.实现 1.编写Partitioner,代码如下 public sta ...

  10. 第三篇:GPU 并行编程的运算架构

    前言 GPU 是如何实现并行的?它实现的方式较之 CPU 的多线程又有什么分别? 本文将做一个较为细致的分析. GPU 并行计算架构 GPU 并行编程的核心在于线程,一个线程就是程序中的一个单一指令流 ...