1. 程式人生 > 其它 >軟體安全-1.資料優化

軟體安全-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();"