关于并发你真的了解吗?(三)
本文仅代表带个人观点及理解,本人只是一个编程小菜鸟,如果有不对的地方。请大佬轻喷!
前言:很多程序员认为像“并发”这么高级的内容离自己很遥远甚至是毫无关系。当我听到这个想法的时候,说实话我很惊讶。实际上并发处理这个词语是与程序员日常工作中所编写的程序息息相关的。试想一下,如果一个程序原本响应速度平均1秒(举例而已,大佬们不要认真)。而由于工作中不注重代码规范,性能等问题。导致响应速度变成了2秒,那么您整体的并发处理还能保持原有的速度吗?要知道每个应用程序池的线程数量是有限的如果单个线程响应速度变慢了一倍,不仅延长了后续其他列队的处理。还有可能会导致列队上限从而引发响应超时,无法访问等问题。(不清楚ISS的可以查看 《关于并发你真的了解吗?(一)》 http://www.cnblogs.com/xinwuhen/p/7049093.html)而这个效率最少降低了一倍以上,一倍是什么概念。这导致公司为了处理高并发问题可能要再投入一倍的财力来搭建机房,这导致原本可以处理的并发数量。“现在”变成了各种访问超时,无法访问!本文将为您介绍日常工作中如何优化性能和日常编程过程中"如何提高并发处理效率"(提高响应速度间接等于提高并发处理能力嘛)。
本文按照两部分来介绍开发过程中需要注意的地方,第一部分总体说明,第二部分抽出其中一项:代码质量来重点说明一下。
总体说明:
1.有一些童鞋喜欢在网上扒一些插件,自定义控件等使用。并且一般都不会查看插件,控件源码。现在的插件,控件很垃圾,不但占服务器资源,而且会使网站运行变慢。去掉垃圾的插件,用标准版!或者自己定义高性能控件。
2.页面嵌套,在一个页面中显示另一个页面的内容。用户的一次访问对服务器来说却是两次或以上。尽量不要采用框架的形式制作页面!
3.页面静态化- 用户可以直接获取页面,不用走那么多流程,比较适用于页面不频繁更新。
4.使用缓存- 第一次获取数据从数据库准提取,然后保存在缓存中,以后就可以直接从缓存提取数据。不过需要有机制维持缓存和数据库的一致性。
5.您的网站图片,文件等资源被人盗链!要防止盗连情况的发生!
6.批量读取 - 高并发情况下,可以把多个请求的查询合并到一次进行,以减少数据库的访问次数
7.延迟修改 - 高并发情况下,可以把多次修改请求,先保存在缓存中,然后定时将缓存中的数据保存到数据库中,风险是可能会断电丢失缓存中的数据
8.使用索引 - 索引可以看作是特殊的缓存,尽量使用索引就要求where字句中精确的给出索引列的值。
9.使用储存过程-那些处理一次请求需要多次访问数据库的操作,可以把操作整合到储存过程,这样只要一次数据库访问就可以了。另外存储过程也节省了预编译的过程,进而打到节省时间的作用。使用存储过程来代替SQL语句查询,还可以在编写存储过程中加入一定的逻辑,从而提高程序的安全性。
10.使用性能较高的SQL语句,很多童鞋在写SQL语句的时候图方便。直接写 Select *或者Count(*)等语句,但是你可知道Select *和Select 列明 在大数据情况下会产生几倍的差距。而Count(1)和Count(*)的差距更是无法想象的。
11.养成检查代码的好习惯,避免因代码质量造成宕机。
12.提高代码质量
提高代码质量
一.++i和i++引申出的效率问题,至于整型变量的前加和后加的区别相信大家也是很清楚的。但却是一般编程过程中最容易忽视的一个问题。
二.循环引发的问题(循环内定义,还是循环外定义对象)
请看下面的两段代码:
三.局部变量VS静态变量
四.减少除法运算的使用
五.尽量避免复制对象
六.数组添加性能>泛型List<T> (由于本文篇幅过长,下文不在一一举例,如果需要了解的童鞋可以自行查阅一下相关文档)
七.List<T>性能 > Dictionary<T, T>性能
八.for性能>foreach性能
九.Model时,struct性能>class (不得不说内容)
相信对于一些初入编程的童鞋来说并不清楚struct或者从未使用甚至没有见过。如下代码,可自行拷贝使用一下。
struct MyStructure
{
public string Name;
public string Surname;
}
class MyClass
{
public string Name;
public string Surname;
}
class Program
{
static void Main(string[] args)
{
MyStructure [] objStruct =new MyStructure[1000];
MyClass[] objClass = new MyClass[1000];
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; ++i)
{
objStruct[i] = newMyStructure();
objStruct[i].Name = "Sourav";
objStruct[i].Surname = "Kayal";
}
sw.Stop();
Console.WriteLine("For Structure:- "+ sw.ElapsedTicks);
sw.Restart();
for (int i = 0; i < 1000; ++i)
{
objClass[i] = newMyClass();
objClass[i].Name = "Sourav";
objClass[i].Surname = "Kayal";
}
sw.Stop();
Console.WriteLine("For Class:- " + sw.ElapsedTicks);
Console.ReadLine();
}
我的运行结果为(可自行尝试体会):
For Structure:- 46
For Class:- 531
相信性能差距已经一目了然了。
十.对于频繁操作的字符串连接 Stringbuilder性能>String性能(StringBuilder采用的是双链结构)
十一.class成员中,String性能>string
十二.循环外使用try catch 性能 > 循环内使用try catch
总结:虽然在尽力控制篇幅,但是还是写了这么多。当然这些也不是全部的内容,只是列举了一些您可能知道但是也并没有重视的日常开发中的“马虎”。关于日常开发过程中损失性能效率的“马虎”实在太多太多,我也仅仅是总结其中一小部分。但是如果您可以做到上述内容,相信您的程序也会有所改善的!
本文版权归作者 心灬无痕(博文地址:http://www.cnblogs.com/xinwuhen/)所有,欢迎转载和商用,请在文章页面明显位置给出原文链接并保留此段声明,否则保留追究法律责任的权利,其他事项,可留言咨询。