软件安全-1.数据优化
1.1 优化变量赋值
如下代码为求1-1000的和
class Test{
int sum;
void cal(){
for(int i=1;i<1000;i++){
sum+=i;
}
}
}
一般来说,由于局部变量用完之后释放,因此有些作用范围较大的变量操作,改为局部变量来实现,有助于节省宝贵的系统资源,,sum作为类成员变量,在循环中进行反复读取,由于对局部变量进行进行读取,消耗资源较小,因此可以将读取过程交给局部变量去做,代码可改为:
class Test{
int sum;
void cal(){
int temp =sum;
for(int i=1;i<1000;i++){
temp+=i;
}
sum=temp
}
}
在该代码中,对sum的读取和赋值变为了对局部变量temp的访问
1.2 优化字符串
由于字符串的特殊性和灵活性,字符串的优化应用较广
首先由于字符串的池子机制,字符串的初始化(分配内存过程)就可以优化
先看如下代码;
String str = new String("china");
该代码中,系统实例化一个新的对象str,为其分配内存空间.但是由于字符串使用了池机制,可以将上面代码优化如下:
String str = "china";
此代码中,系统首先检查池中有无"china",如果有,系统将直接使用池中的字符串,而不用新分配内存空间.
一般情况下,由于字符串常量的出现都会附带为其分配内存空间,因此,能够避免字符串常量出现的场合,可以尽量避免.
如下代码:
String s;
if(s.equals("")){
//一些操作
}
该代码将字符串s和空字符串相比较,虽然空字符串中没有内容,但是也要占用字符串所规定的内存空间.因此,可以使用如下代码避免:
String s;
if(s.length()==0){
//一些操作
}
又如,如下代码:
StringBuffer sb;
String str = ",";
for(int i = 0;i<10;i++){
sb.append(i);
sb.append(str);
}
该代码中,字符串str中只包含一个逗号,如果用字符串的形式来保存,必用字符形式保存消耗的资源要多.因此,该代码可以做出如下优化:
StringBuffer sb;
for(int i =0;i<10;i++){
sb.append(i);
sb.append(',')
}
将逗号用字符表示,节省系统资源.
此外,在对多个字符串进行操作或对一个字符串进行修改时,用StringBuffer比用String更好
如下代码:
String str = "s1";
String str = "s2";
String str3= str1 + str2;
str3将保存str1和str2连在一起的结果,系统将为str3额外分配内存.为了避免这个额外的资源消耗,代码可以优化如下:
StringBuffer sb = new StringBuffer("s1");
String str2 = "s2";
sb.append(str2);
这样就不需要为两个字符连在一起的结果额外分配内存
1.3 选择合适的数据结构
在实际开发中,选择一种合适的数据结构很重要.比如,有一堆随机存放的数据,如果经常在其中进行插入删除操作,使用链表较好;如果经常进行读取,并数据个数固定,则使用数组较好.
在C中,数组与指针语句具有十分密切的关系,一般来说,指针的好处是比较灵活简洁,而数组则比较直观容易理解.与数组索引相比,指针一般能使代码运行速度更快,执行效率更高.这种情况,在使用多维数组使差异更明显.
下面代码作用是相同的,但是效率不一样:
数组索引:
for(;;){
sum+=array[t++];
}
指针运算:
p = array;
for(;;){
sum+=*(p++)
}
在该代码的指针版本中,array的地址每次赋值给地址p后,在每次循环中秩序对指针p进行增量操作.在数组索引版本中,每次循环中都必须进行根据t值求数组下标的复杂运算
1.4 使用尽量小的数据类型
为了保证空间不被浪费,在使用数据类型的过程中,可以做到:
- 能够使用字符型(char)定义的变量的情况下,就不要使用整形(int)变量来存储数据
- 能够使用整型变(int)量定义的变量就不要用长整型(long int)
- 能够使用浮点型(float)变量就不要使用双精度型(double)变量
必须要保证,在定义变量后,变量的值不要超过变量所容纳的范围
1.5 合理使用集合
很多语言中都有集合的概念,某些集合的存储实际上使用数组,如java中的Vector,ArrayList
以Vector为例,Vector的使用与数组类似,它的元素可以通过整数形式的索引访问.但是,Vector类型对象在创建之后,对象的大小能够根据元素的增加或者删除而扩展,缩小
在使用集合时,尽可能将元素添加到集合后面,可以免除元素的移动
下面的例子:
Vector v = new Vector();
for(int i=0;i<100;i++){
v.add(0,"china");
}
可以改为:
Vector v = new Vector();
for(int i=0;i<100;i++){
v.add("china")
}
同样的规则也适用于Vector类的remove()方法.由于Vector中各元素之间不能含有"空隙",删除最后一个元素之外的任意其他元素都导致被删除元素之后的元素向前移动.也就是说,从Vector删除最后一个元素要比删除第一个元素"开销低好几倍"
假设要从前面的Vector删除所有元素,可以使用这种代码:
for(int i=0;i<100;i++){
v.remove(0);
}
以上代码性能不佳,应该改为:
for(int i=0;i<100;i++){
v.remove(v.size()-1);
}
当然,从Vector类型的对象v删除所有元素的最好方法时使用"v.removeALLElements();"