友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第87章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




      void test(Set s; int size) {  

        for(int i = 0; i 《 REPS; i++)  

          for(int j = 0; j 《 size; j++)  

            s。contains(Integer。toString(j));  

      }  

    };  

    new Tester(〃iteration〃) {   

      void test(Set s; int size) {  

        for(int i = 0; i 《 REPS * 10; i++) {  

          Iterator it = s。iterator();  

          while(it。hasNext())  

            it。next();  

        }  



                                                                                            249 


…………………………………………………………Page 251……………………………………………………………

      }  

    };  

  };  

  public static void test(Set s; int size) {  

    // A trick to print out the class name:  

    System。out。println(〃Testing 〃 +   

      s。getClass()。getName() + 〃 size 〃 + size);  

    Collection1。fill(s; size);  

    for(int i = 0; i 《 tests。length; i++) {  

      System。out。print(tests'i'。name);  

      long t1 = System。currentTimeMillis();  

      tests'i'。test(s; size);  

      long t2 = System。currentTimeMillis();  

      System。out。println(〃: 〃 +   

        ((double)(t2 t1)/(double)size));  

    }  

  }  

  public static void main(String'' args) {  

    // Small:  

    test(new TreeSet(); 10);  

    test(new HashSet(); 10);  

    // Medium:  

    test(new TreeSet(); 100);  

    test(new HashSet(); 100);  

    // Large:  

    test(new HashSet(); 1000);  

    test(new TreeSet(); 1000);  

  }  

} ///:~  

  

⑧:TreeSet 在本书写作时尚未成为一个正式的特性,但在这个例子中可以很轻松地为其添加一个测试。  

  

最后对ArraySet 的测试只有500 个元素,而不是 1000 个,因为它太慢了。  

  

类型 测试大小 添加 包含 反复  

  

  



Type    Test size Add  Contains Iteration  



        10        22。0 11。0     16。0  



TreeSet 100       22。5 13。2     12。1  



        1000      31。1 18。7     11。8  



        10        5。0  6。0      27。0  



HashSet 100       6。6  6。6      10。9  



        1000      7。4  6。6      9。5  



  

  

进行add()以及contains()操作时,HashSet 显然要比ArraySet 出色得多,而且性能明显与元素的多寡关系 

不大。一般编写程序的时候,几乎永远用不着使用 ArraySet 。  

  

3。 决定使用何种Map  



                                                                                            250 


…………………………………………………………Page 252……………………………………………………………

选择不同的 Map 实施方案时,注意 Map 的大小对于性能的影响是最大的,下面这个测试程序清楚地阐示了这 

一点:  

  

//: MapPerformance。java  

// Demonstrates performance differences in Maps  

package c08。newcollections;  

import java。util。*;  

  

public class MapPerformance {  

  private static final int REPS = 200;  

  public static Map fill(Map m; int size) {  

    for(int i = 0; i 《 size; i++) {  

      String x = Integer。toString(i);  

      m。put(x; x);  

    }  

    return m;  

  }  

  private abstract static class Tester {  

    String name;  

    Tester(String name) { this。name = name; }  

    abstract void test(Map m; int size);  

  }  

  private static Tester'' tests = {  

    new Tester(〃put〃) {   

      void test(Map m; int size) {  

        for(int i = 0; i 《 REPS; i++) {  

          m。clear();  

          fill(m; size);  

        }  

      }  

    };  

    new Tester(〃get〃) {   

      void test(Map m; int size) {  

        for(int i = 0; i 《 REPS; i++)  

          for(int j = 0; j 《 size; j++)  

            m。get(Integer。toString(j));  

      }  

    };  

    new Tester(〃iteration〃) {   

      void test(Map m; int size) {  

        for(int i = 0; i 《 REPS * 10; i++) {  

          Iterator it = m。entries()。iterator();  

          while(it。hasNext())  

            it。next();  

        }  

      }  

    };  

  };  

  public static void test(Map m; int size) {  

    // A trick to print out the class name:  

    System。out。println(〃Testing 〃 +   

      m。getClass()。getName() + 〃 size 〃 + size);  



                                                                                          251 


…………………………………………………………Page 253……………………………………………………………

    fill(m; size);  

    for(int i = 0; i 《 tests。length; i++) {  

      System。out。print(tests'i'。name);  

      long t1 = System。currentTimeMillis();  

      tests'i'。test(m; size);  

      long t2 = System。currentTimeMillis();  

      System。out。println (〃: 〃 +   

        ((double)(t2 t1)/(double)size));  

    }  

  }  

  public static void main(String'' args) {  

    // Small:  

    test(new Hashtable(); 10);  

    test(new HashMap(); 10);  

    test(new TreeMap(); 10);  

    // Medium:  

    test(new Hashtable(); 100);  

    test(new HashMap(); 100);  

    test(new TreeMap(); 100);  

    // Large:  

    test(new HashMap(); 1000);  

    test(new Hashtable(); 1000);  

    test(new TreeMap(); 1000);  

  }  

} ///:~  

  

由于Map 的大小是最严重的问题,所以程序的计时测试按Map 的大小(或容量)来分割时间,以便得到令人 

信服的测试结果。下面列出一系列结果(在你的机器上可能不同):  

  

类型 测试大小 置入 取出 反复  

  



T y p e     T e s t   Put   Get     Iteration  

           s i z e   



           10       11。0   5。0      44。0  



Hashtable 100       7。7     7。7     16。5  



           1000     8。0     8。0     14。4  



           10       16。0   11。0   22。0  



TreeMap  100        25。8   15。4   13。2  



           1000     33。8   20。9   13。6  



           10       11。0   6。0      33。0  



HashMap  100        8。2     7。7     13。7  



           1000     8。0     7。8     11。9  



  

  

即使大小为 10,ArrayMap 的性能也要比HashMap 差——除反复循环时以外。而在使用Map 时,反复的作用通 

常并不重要(get()通常是我们时间花得最多的地方)。TreeMap 提供了出色的 put()以及反复时间,但 get() 

的性能并不佳。但是,我们为什么仍然需要使用TreeMap 呢?这样一来,我们可以不把它作为Map 使用,而 

作为创建顺序列表的一种途径。树的本质在于它总是顺序排列的,不必特别进行排序(它的排序方式马上就 

要讲到)。一旦填充了一个TreeMap,就可以调用keySet()来获得键的一个Set “景象”。然后用toArray() 



                                                                                                   252 


…………………………………………………………Page 254……………………………………………………………

产生包含了那些键的一个数组。随后,可用 static 方法Array。binarySearch()快速查找排好序的数组中的 

内容。当然,也许只有在HashMap 的行为不可接受的时候,才需要采用这种做法。因为HashMap 的设计宗旨 

就是进行快速的检索操作。最后,当我们使用 Map 时,首要的选择应该是 HashMap。只有在极少数情况下才 

需要考虑其他方法。  

此外,在上面那张表里,有另一个性能问题没有反映出来。下述程序用于测试不同类型Map 的创建速度:  

  

//: MapCreation。java  

// Demonstrates time differences in Map creation  

package c08。newcollections;  

import java。util。*;  

  

public class MapCreation {  

  public static void main(String'' args) {  

    final long REPS = 100000;  

    long t1 = System。currentTimeMillis();  

    System。out。print(〃Hashtable〃);  

    for(long i = 0; i 《 REPS; i++)  

      new Hashtable();  

    long t2 = System。currentTimeMillis();  

    System。out。println(〃: 〃 + (t2 t1));  

    t1 = System。currentTimeMillis();  

    System。out。print(〃TreeMap〃);  

    for(long i = 0; i 《 REPS; i++)  

      new TreeMap();  

    t2 = System。currentTimeMillis();  

    System。out。println(〃: 〃 + (t2 t1));  

    t1 = System。currentTimeMillis();  

    System。out。print(〃HashMap〃);  

    for(long i = 0; i 《 REPS; i++)  

      new HashMap();  

    t2 = System。currentTimeMillis();  

    System。out。println(〃: 〃 + (t2 t1));  

  }  

} ///:~  

  

在写这个程序期间,TreeMap 的创建速度比其他两种类型明显快得多(但你应亲自尝试一下,因为据说新版 

本可能会改善ArrayMap 的性能)。考虑到这方面的原因,同时由于前述TreeMap 出色的put()性能,所以如 

果需要创建大量Map,而且只有在以后才需要涉及大量检索操作,那么最佳的策略就是:创建和填充 

TreeMap;以后检索量增大
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!