国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

你知道數(shù)據(jù)大小嗎?

2019-11-18 12:09:15
字體:
供稿:網(wǎng)友

  --不要花太多的功夫來隱藏類的成員(三)
  
  你知道數(shù)據(jù)大小嗎?--不要花太多的功夫來隱藏類的成員(三)  copyright(翻譯
   
  要害字   數(shù)據(jù)大小 對象大小 堆空間
   
  出處   http://www.javaworld.com/javaworld/javatips/jw-javatip130-p3.Html
   
  我們能做點什么呢?
  
  “這很好,但是我們沒有任何選擇除了使用String和其它Java提供的類型,是不是這樣呢?”我聽到你們再問,那么讓我們來找找答案吧。
  
  l     封裝類
  
  封裝類比如java.lang.Integer,看起來保存大量的數(shù)據(jù)在內(nèi)存中像一個壞的選擇。假如你盡力為了內(nèi)存的經(jīng)濟(jì),那么就要避免這么做。使用你自己的針對int的向量類并不難。當(dāng)然,假如Java的核心函數(shù)庫已經(jīng)包含了這個那就最好不過了?;蛟S這種情況在Java擁有非凡類型的時候?qū)蟠蟾挠^。
  
  l     多位數(shù)組
  
  對于使用多維數(shù)組的大型的數(shù)據(jù)結(jié)構(gòu),你可以時常的通過簡單的索引變換減少額外的維數(shù)/例如:轉(zhuǎn)換int[dim1][dim2]的實例到一個int[dim1*dim2]的實例,改變所有形如a[i][j]的表達(dá)式為a[i*dim1+j]。這樣你就不必花功夫在dim1上的索引檢查可以提高效率。
  
  l     java.lang.String
  
  你可以使用一些小技巧去減少你的應(yīng)用中字符串的靜態(tài)內(nèi)存大小。
  
  首先,你可以嘗試一種很平常的技術(shù),就是當(dāng)一個應(yīng)用從一個數(shù)據(jù)文件或者網(wǎng)絡(luò)連接中載入或者緩存很多的字符串,并且這種字符串的值是有限變化的。舉個例子:假如你想分析一個xml文件,在這個文件中,你經(jīng)常碰到某種屬性,但是這個屬性僅僅被限制在兩個可能的值。你的目標(biāo):通過一個散列映射過濾所有的字符串,減少所有相同的但是明顯字符串和目標(biāo)對象引用一樣的。
  
    public String internString (String s)
    {
      if (s == null) return null;
      String is = (String) m_strings.get (s);
      if (is != null)
        return is;
      else
      {
        m_strings.put (s, s);
        return s;
      }
    }
  
    PRivate Map m_strings = new HashMap ();
  
  假如適用成功,這個技巧能夠成倍的減少你的靜態(tài)內(nèi)存需求。一個富有經(jīng)驗的讀者應(yīng)該能夠觀察到這個技巧復(fù)制java.lang.String.intern()的功能性。有無數(shù)的理由存在來讓你避免使用String.intern()方法。其中一個就是現(xiàn)在的JVM幾乎沒有能實現(xiàn)大量數(shù)據(jù)的保留。
  
  假如你的字符串是完全不同的,會發(fā)生什么情況呢?這就是要介紹的第二個技巧,重新收集那些小的字符串空間,這些空間潛在的隱藏于char數(shù)組中,因為使用數(shù)組大概只占了字符串封裝所占用的內(nèi)存的一半。因此,當(dāng)我們的應(yīng)用緩存許多獨特的字符傳值,我們僅僅只要保持在內(nèi)存中的數(shù)組,在需要的時候轉(zhuǎn)換為字符串。假如這個字符串只是作為暫時的,很快就會拋棄,這將很有效果。一個簡單的實驗就是從一個字典文件中選出作為緩存的90000個單詞,這些數(shù)據(jù)大約5.6M的大小,假如是char的話,只需要3.4M的空間,只占用了以前的65%。
  
  第二個技巧明顯的包含一個不利條件,就是你不能支持通過一個構(gòu)造函數(shù)轉(zhuǎn)換一個char[]成為字符串,因為這個構(gòu)造函數(shù)沒有復(fù)制這個數(shù)組而將擁有這個數(shù)組。為什么呢?因為這個完全的public的字符串API確保每一個字符串是不可變的,所以每個字符串的構(gòu)造函數(shù)顯然要復(fù)制輸入的數(shù)據(jù)然后傳入它的參數(shù)。
  
  然后,我們將使用第三個技巧。這個技巧用在當(dāng)轉(zhuǎn)換一個char數(shù)組為一個字符串的代價證實太高的時候。該技巧使用java.lang.String.substr()的功能避免數(shù)據(jù)復(fù)制:這個方法的是顯示用了字符串的不變性,并且創(chuàng)建的一個影子字符串對象來共享字符內(nèi)容,但是它的內(nèi)部的開始位置和結(jié)束位置都是正確的。我們還是寫一個例子,new String(“smiles”).substring(1,5)是一個字符串,這個字符串是字符緩沖從位置1到位置4的字符結(jié)束,并且這個字符緩沖將共享原來的字符串構(gòu)造函數(shù)指向的字符緩沖。你可以象一下這樣使用:給出一個大的字符串集合,你可以合并它的字符內(nèi)容到一個大的字符數(shù)組,在它之上創(chuàng)建一個字符串,并且使用這個主串的子串來重新創(chuàng)建一個原來的字符串。如以下描述:
    public static String [] compactStrings (String [] strings)
    {
      String [] result = new String [strings.length];
      int offset = 0;
      for (int i = 0; i < strings.length; ++ i)
        offset += strings [i].length ();
      // Can't use StringBuffer due to how it manages capacity
      char [] allchars = new char [offset];
      offset = 0;
      for (int i = 0; i < strings.length; ++ i)
      {
        strings [i].getChars (0, strings [i].length (), allchars, offset);
        offset += strings [i].length ();
      }
      String allstrings = new String (allchars);
      offset = 0;
      for (int i = 0; i < strings.length; ++ i)
        result [i] = allstrings.substring (offset,
                         offset += strings [i].length ());
      return result;
    }
  
  以上方法返回一個新的字符串集等同于輸入的字符串集,但是在內(nèi)存中更加得緊湊。重新獲得每個字符串?dāng)?shù)組的16個字節(jié)的頭部,在方法中被有效的移除。這個存儲在緩存壓縮大多數(shù)短的字符串時比較有效果。當(dāng)這個方法用于同樣的90000個單詞的字典時,內(nèi)存從5.6M節(jié)約到4.2M,大概節(jié)約了30%。
  
  l     這些努力是否值得呢?
  我這里提到的方法看起來都是很細(xì)微的優(yōu)化,是否值得花時間去實現(xiàn)呢?但是,記住我們腦子里面應(yīng)該記?。悍?wù)端的應(yīng)用程序能夠緩存大量的數(shù)據(jù)在內(nèi)存中的話講能夠大大的提高從磁盤和數(shù)據(jù)庫提取數(shù)據(jù)的性能和效率。在當(dāng)前32位的JVM中,幾百兆的緩存數(shù)據(jù)代表堆中很引人注重的位置。減少30%或者更多不應(yīng)該被嘲笑,它能將系統(tǒng)的可測性質(zhì)中能提高很顯著的水平。當(dāng)然這些技巧不適用于一開始就很好設(shè)計的數(shù)據(jù)結(jié)構(gòu),事實的決定要由hotspots來決定。無論如何,你現(xiàn)在應(yīng)該更加了解你的對象消耗了多少內(nèi)存。
  
  關(guān)于作者:
  Vladimir RouBTsov擁有超過12年的多種語言的編程經(jīng)驗,其中包括從1995年就開始用得Java。目前,它作為資深開發(fā)者在Austin, Texas.為Trilogy開發(fā)企業(yè)級軟件。平時的業(yè)余愛好就是開發(fā)一些關(guān)于Java字節(jié)代碼或源程序代碼的工具。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 亚东县| 漳浦县| 锡林郭勒盟| 临泉县| 新民市| 巢湖市| 宜兰县| 民乐县| 赞皇县| 海宁市| 上犹县| 南靖县| 日喀则市| 双桥区| 昂仁县| 石河子市| 新余市| 金门县| 吉木乃县| 巴马| 贵州省| 南丹县| 尼勒克县| 济宁市| 阿拉善右旗| 日土县| 安溪县| 白银市| 昌图县| 江都市| 平顶山市| 青铜峡市| 剑川县| 武冈市| 黄梅县| 邮箱| 商南县| 武清区| 威海市| 阿合奇县| 开平市|