前一篇分析了求质数的两个算法,在代码执行效率和系统开销两方面进行了比较。
这在通信系统的设计和实现中,是非常重要的两点。因为需要同时面对的是巨大的用户群,和复杂的业务应用,通信系统的设计经常要面临鱼与熊掌间的选择。
用最简单和最形象的比喻,就是使用数组还是用链表结构来存储和处理数据。很多时候,硬件的资源是无法提供对数组的支持的。这时候,不得不使用链表结构的算法,而继续的优化算法也非常必要。
还是用求质数的算法来做说明。 ^_^
[1]这是最原始的算法,处理9000个用户数据,需要2600ms。面对10000个用户时,崩溃!
var stopwatch = new Date();
var PrimeArys = [2];
var count = 1;
var isss = 0;
var MaxNum = 9000;
for(var i=3 ;i<=MaxNum;i+=2)
{
isss = 0;
for(var j=3;j<(i/2);j+=2)
{
if(i%j==0){
isss = 1;
break;
}
}
if(isss == 0){
{
PrimeArys[ count++ ] = i;
}
}
}
var t=new Date()-stopwatch;
alert("本次运行了 "+t+" 毫秒。");
[2]分析前面的算法,发现只要不能被某个已知质数整除,就必然不能被该质数的倍数整除。所以,检查的因子就只限于已知的质数列表就可以了。这个算法,在处理9000个数据的时候,只开销了1593ms!
var stopwatch = new Date();
var PrimeArys = [2];
var count = 1;
var isss = 0;
var MaxNum = 9000;
for(var i=3 ;i<=MaxNum;i+=2)
{
isss = 0;
for(var j=0;j<count;j++)
{
if(i%PrimeArys[j]==0){
isss = 1;
break;
}
}
if(isss == 0){
{
PrimeArys[ count++ ] = i;
}
}
}
var t=new Date()-stopwatch;
alert("本次运行了 "+t+" 毫秒。");
var PrimeArys = [2];
var count = 1;
var isss = 0;
var MaxNum = 9000;
for(var i=3 ;i<=MaxNum;i+=2)
{
isss = 0;
for(var j=0;j<count;j++)
{
if(i%PrimeArys[j]==0){
isss = 1;
break;
}
}
if(isss == 0){
{
PrimeArys[ count++ ] = i;
}
}
}
var t=new Date()-stopwatch;
alert("本次运行了 "+t+" 毫秒。");
[3]继续分析下去,没有一个数字是可以被超过自己一半的数字整除的,所以,继续优化,这样处理9000个用户只开销了1312ms。算法的优化到此,已经可以支持15000个用户了,这比起原始算法只支持9000,是一个巨大的提升!
var stopwatch = new Date();
var PrimeArys = [2];
var count = 1;
var isss = 0;
var MaxNum = 15000;
for(var i=3 ;i<=MaxNum;i+=2)
{
isss = 0;
for(var j=0;j<count;j++)
{
if(i%PrimeArys[j]==0){
isss = 1;
break;
}
}
if(isss == 0){
{
PrimeArys[ count++ ] = i;
}
}
}
var t=new Date()-stopwatch;
alert("本次运行了 "+t+" 毫秒。");
var PrimeArys = [2];
var count = 1;
var isss = 0;
var MaxNum = 15000;
for(var i=3 ;i<=MaxNum;i+=2)
{
isss = 0;
for(var j=0;j<count;j++)
{
if(i%PrimeArys[j]==0){
isss = 1;
break;
}
}
if(isss == 0){
{
PrimeArys[ count++ ] = i;
}
}
}
var t=new Date()-stopwatch;
alert("本次运行了 "+t+" 毫秒。");
如上可见,在面对真实的应用场景时,合理的算法实现的重大意义。