一、加速思路
- 代码优化
- 压缩输出
- 内容缓存输出
- 函数缓存输出
- 加速/缓存工具软件
1.减少连接数
HTTP1.1协议里,一个浏览器窗口会打开2个连接。不同的浏览器和版本,就此限制有所区别。减少弹出窗口,可以有效增加服务器连接数。在不是必要的地方,减少弹出窗口。
其它网站做图片友情链接的时候,不要把图片链接到本站。
2.能用Cookie的地方,不要用Session
Session在服务器需要占用资源。
3.避免频繁操作缓存
4.运行环境设置 - 限制数据库使用的内存和CPU资源。
- 限制每个站点使用的资源。
- 禁止多余的Web服务扩展
- 删除不必要的IIS扩展名映射
- 取消不必要的访问记录
- 减少不必要的服务器协议
- 数据库与日志分在不同分区
- 负载均衡与 集群
- 流量控制
- 服务降级
- 合理调整批量计划
二、PHP加速
1.测试脚本运行时间
<?php
function gettime(){
$nowtime = explode(' ',microtime());
return $nowtime[0]+$nowtime[1];
}
$start = gettime();
//相关操作,脚本运行 和 读取数据 等操作
$end = gettime();
$count =$end-$start;
echo ' 用时:'.$count;
?>
2.测试三种方法打印字符串的执行效率
在我们的程序里面,经常会需要用到打印字符串的地方,我们会经常用echo来输出一段字符串变量,更多的是组合文本,变量,数组,数值来输出。
组合这些不同类型的变量方式有很多,但我们需要找出最有效率的一种。下面我们就写一个测试代码,来检测真正快速有效率的那一种方法。
<?php
define('MAXTEST', 100000);
$f = "charse";
$g = "zhang";
$k = array("fine", 2249, 'blablabla');
//sprintf 函数连接
$start_time = microtime(true);
for($i=0;$i<MAXTEST;$i++)
{
echo sprintf("<!--ni %s hao %s ma %s de %s bi %s -->", $f, $g , $k[0], $k[1], $k[2]);
}
$end_time = microtime(true);
echo $end_time - $start_time;
echo "<br />";
flush();
sleep(1);
//双引号 和 . 连接
$start_time = microtime(true);
for($i=0;$i<MAXTEST;$i++)
{
echo "<!-- ni ".$f." hao ".$g." ma ".$k[0]." de ".$k[1]." bi ".$k[2]." -->";
}
$end_time = microtime(true);
echo $end_time - $start_time;
echo "<br />";
flush();
sleep(1);
//单引号 和 , 连接
$start_time = microtime(true);
for($i=0;$i<MAXTEST;$i++)
{
echo '<!-- ni ',$f,' hao ',$g,' ma ',$k[0],' de ',$k[1],' bi ',$k[2],' -->';
}
$end_time = microtime(true);
echo $end_time - $start_time;
echo "<br />";
flush();
根据我们的测试结果,用单引号加上逗号连接不同变量是最快的连接字符串方法。
如果echo后面直接跟要输出的内容,我们可以用单引号和逗号来组织串联这些字符及变量。
单引号不能用于给变量赋值的情况。给变量赋值,可以用英文句号连接字符串和变量。
sprintf是用来格式化字符串,它会根据提供的模板和变量,输出格式化好的字符串。
3.Include比简单处理xml快30%,随着处理复杂度的增加,性能相差会更大。
4.查找数组
array_search从算法角度来说,不算很好。他会便利数组项,时间复杂度为N。
在需要搜索值的环境下,尽可能的做一些变通。在查找值时,将数组的键取出并构造一个新的数组,如下:
assocarray=arrayflip(arraykeys(
array));
此时查找任意一个数组项,速度将会非常的快。我们只要用一下的方式来检测值的存在性,如下:
if(isset(
assocarray[
value])) …
//或者
if(array_key_exists(
value,
assoc_array)) …
同时,也是一个典型的空间换时间算法。
5.删除可用数组
php中,删除数组中重复元素有一个可用的函数,那就是array_unique(), 但是它并不是一个最高效的方法,使用array_flip()函数将比array_unique()在速度上高出五倍左右。
函数格式:
array array_flip ( array trans ) //array_flip – 交换数组中的键和值
方法如下:
$arr = array(…………) ;//假设有一万个元素的数组,里面有重复的元素。
$arr = array_flip(array_flip($arr)); //这样便可以删除重复元素。
究竟是怎么回事呢?来看下array_flip()的作用:array_flip()用于将一个数组的每个元素的键和值交换,如:
$arr1 = array ("age" => 30, "name" => "php自学网");
$arr2 = array_flip($arr1); //$arr2 就是 array(30 => "age", "php自学网" => "name");
在PHP的数组中,允许不同的元素可以取同一个值,但不允许同一个键名被不同的元素使用,如:
$arr1 = array ("age" => 30, "name" => "php自学网", "age" => 20); "age" => 20将会取代"age" => 30
$arr1 = array ("name" => "php自学网", "age" => 45);
这里 $arr1与$arr2 是相等的。
于是,我们便可以知道,为什么 array_flip(array_flip($arr)) 可以删除数组中重复的元素了。首先,$arr里的值会变成键名,因为值是有重复的,变成键名之后这些重复的值便成了重复的键名,PHP引擎将重复的键名删除,只保留最后一个。如:
$arr1 = array ("age" => 30, "name" => "php自学网", "age" => 20);
$arr1 = array_flip($arr1); //$arr1 变成了 array("php自学网" => "name", 20 => "age");
//再把 $arr1 的键名与值还复:
$arr1 = array_flip($arr1);
上面的代码写得简洁一些就是: $arr1 = array_flip(array_flip($arr1));
6.Switch 机率大的放前面
7.系统设置性的东西,写到PHP文件,不要存到数据库
如首页标题 、 描述 、 关键词等,直接写到PHP文件,可以用Include引用,后台设置以后,也直接生成html格式文件。
8.不要轻易判断硬盘上的文件是否存在
硬盘上的文件如果不存在,PHP的判断语句执行会非常慢。
9.回收内存
在指向一个对象的所有引用都删除后,删除大于256字节的对象
三、.Net
对必要的对象必需释放,特别是数据库连接对象。.Net的using语句块可以对局部变量自动销毁,可以尽量多用。
.Net程序避免使用Office对象。
四、JS加速
1.JS组合字符串
在脚本开发过程中,经常会按照某个规则,组合拼接出一个大字符串进行输出。比如写脚本控件时控制整个控件的外观的HTML标签输出,比如AJAX里得到服务器端的回传值后动态分析创建HTML标签时,不过这里我就不讨论拼接字符串的具体应用了,我只是想在这里讨论一下拼接的效率。
字符串的拼接在我们写代码的时候都是用“+=”这个运算符,s += String; 这是我们最为熟知的写法,不知道大家有没有注意过没有,在组合的字符串容量有几十K甚至几百K的时候,脚本执行起来很慢,CPU使用率狂高,例如:
var str = "01234567891123456789212345678931234567894123456789";
str+= "51234567896123456789712345678981234567899123456789\n";
var result = "";
for(var i=0; i<2000; i++) result += str;
就这么一步操作,产生的结果字符串是200K,耗时是1.1秒(这个与电脑配置有关),CPU的峰值100%。(为了更直观地看到效果,我多做了些循环)。可想而知就这么一步操作就消耗了我一秒多的时间,再加上其它的代码的时间消耗,那整个脚本块的执行时间就难以忍受了。那有没有优化的方案呢?还有其它的方法吗?答案当然是有的,否则我写这篇文章就是废话。
更快的方式就是使用数组,在循环拼接的时候不是相接拼接到某个字符串里去,而是把字符串放到一个数组里,最后用数组.join("") 得到结果字符串,代码示例:
var str = "01234567891123456789212345678931234567894123456789";
str+= "51234567896123456789712345678981234567899123456789\n";
var result = "", a = new Array();
for(var i=0; i<2000; i++) a[i] = str;
result = a.join(""); a = null;
大家可以测试测试,组合出一个相同大小的字符串所消耗的时间,我这里测试出来的结果是:<15毫秒,请注意,它的单位是毫秒,也就是说组合出这么一个200K的字符串,两种模式的时间消耗是差不多两个数量级。这意味着什么?意味着后者已经工作结束吃完中饭回来,前者还在做着苦力。我写一个测试页面,大家可以把下面这些代码拷贝下来另存为一个HTM文件在网页里打开自己来测试一下两者之间的效率差,反正我测试的是前者要半分钟才能完成的事,后者0.07秒就搞定了(循环10000次)。
<body>
字符串拼接次数<input id="totle" value="1000" size="5" maxlength="5">
<input type="button" value="字符串拼接法" onclick="method1()">
<input type="button" value="数组赋值join法" onclick="method2()"><br>
<div id="method1"> </div>
<div id="method2"> </div>
<textarea id="show" style="width: 100%; height: 400"></textarea>
<SCRIPT LANGUAGE="JavaScript">
<!--
//这个被拼接的字符串长是100字节 author: meizz
var str = "01234567891123456789212345678931234567894123456789";
str+= "51234567896123456789712345678981234567899123456789\n";
//方法一
function method1()
{
var result = "";
var totle = parseInt(document.getElementById("totle").value);
var n = new Date().getTime();
for(var i=0; i<totle; i++)
{
result += str;
}
document.getElementById("show").value = result;
var s = "字符串拼接法:拼接后的大字符串长 "+ result.length +"字节,"+
"拼接耗时 "+ (new Date().getTime()-n) +"毫秒!";
document.getElementById("method1").innerHTML = s;
}
//方法二
function method2()
{
var result = "";
var totle = parseInt(document.getElementById("totle").value);
var n = new Date().getTime();
var a = new Array();
for(var i=0; i<totle; i++)
{
a[i] = str;
}
result = a.join(""); a=null;
document.getElementById("show").value = result;
var s = "数组赋值join法:拼接后的大字符串长 "+ result.length +"字节,"+
"拼接耗时 "+ (new Date().getTime()-n) +"毫秒!";
document.getElementById("method2").innerHTML = s;
}
//-->
</SCRIPT>
字符串拼接就一律使用数组join呢?这个要看你的实际需求了,就普通的几个或者K级的字节的组合就没有必要使用数组法了,因为开数组变量也是有消耗的。若有几K以上的字符串组合,那就是数组的效率高了。
- IE 6.0:
字符串拼接法:拼接后的大字符串长 1010000字节,拼接耗时 22089毫秒!
数组赋值join法:拼接后的大字符串长 1010000字节,拼接耗时 218毫秒! - Firefox 1.0:
字符串拼接法:拼接后的大字符串长 1010000字节,拼接耗时 1044毫秒!
数组赋值join法:拼接后的大字符串长 1010000字节,拼接耗时 1044毫秒! - Mozilla 1.7:
字符串拼接法:拼接后的大字符串长 1010000字节,拼接耗时 1045毫秒!
数组赋值join法:拼接后的大字符串长 1010000字节,拼接耗时 1044毫秒! - Netscape 7.0:
字符串拼接法:拼接后的大字符串长 1010000字节,拼接耗时 10273毫秒!
数组赋值join法:拼接后的大字符串长 1010000字节,拼接耗时 1138毫秒! - Opera 7.54:
字符串拼接法:拼接后的大字符串长 1010000字节,拼接耗时 6968毫秒!
数组赋值join法:拼接后的大字符串长 1010000字节,拼接耗时 6922毫秒!
循环10000次的测试结果表明在IE和Netscape里可以大大提高效率,而在Firefox Mozilla - Opera 里两种方法耗时基本相近,这些数据足可以判定数组join法优于传统字符串拼接。
五、数据库加速
六、Css加速
1.图片指定大小
图片指定大小可以提高HTML渲染引擎的速度
七、HTML加速
1.防止图片、脚本指向目录
由于各种浏览器对空的解释不一样,要避免出现指向目录的情况,特别注意,避免href或src属性为空。
八、缓存加速
一、服务器侧优化
1. 添加 Expires 或 Cache-Control 信息头
某些经常使用到、并且不会经常做改动的图片(banner、logo等等)、静态文件(登录首页、说明文档等)可以设置较长的有效期(expiration date),这些HTTP头向客户端表明了文档的有效性和持久性。如果有缓存,文档就可以从缓存(除已经过期)而不是从服务器读取。接着,客户端考察缓存中的副本,看看是否过期或者失效,以决定是否必须从服务器获得更新。
2. 压缩内容
3. 设置 Etags