2015-04-30 18 views
10

Tôi đi vào vấn đề này ngày hôm nay và tôi không thể hiểu tại sao mảng groovy không mở rộng quy mô tốt hơn Bản đồ khi nó trở nên lớn hơn.Tại sao Bản đồ của Groovy lại tốt hơn Array?

Trong ví dụ của tôi, tôi tạo Bản đồ (LinkedHashMap) và một mảng Chuỗi (Chuỗi []). Sau đó, tôi lặp lại từ 0 đến 10^7 chèn i vào Bản đồ hoặc Mảng. Tôi làm điều đó 10 lần để chắc chắn rằng các ngoại lệ không làm hỏng kết quả.

int max = 10**7 
int numTests = 10 

long totalTimeMap = 0 
long totalTimeArray = 0 

numTests.times{ 
    long start = System.currentTimeMillis() 

    Map m = [:] 
    max.times { 
     m[it] = "${it}" 
    } 

    long end = System.currentTimeMillis() 
    totalTimeMap += (end-start) 
} 

numTests.times { 
    long start = System.currentTimeMillis() 

    String[] s = new String[max] 
    max.times{ 
     s[it] = "${it}" 
    } 

    long end = System.currentTimeMillis() 
    totalTimeArray += (end-start) 
} 

println "Map: ${totalTimeMap}" 
println "Array: ${totalTimeArray}" 

Kết quả thật bất ngờ kể từ khi Map đã có một hiệu suất tốt hơn sau đó Array:

Map: 49361 
Array: 101123 

tôi đã thực hiện thí nghiệm tương tự trong java:

public static void main(String[] args) { 

     int max = 10000000; 
     int numTests = 10; 

     long totalTimeMap = 0; 
     long totalTimeArray = 0; 

     for(int i=0; i<numTests; i++){ 
      long start = System.currentTimeMillis(); 

      Map m = new LinkedHashMap(); 
      for(int j=0; j<max; j++){ 
       m.put(j, "" + j); 
      } 

      long end = System.currentTimeMillis(); 
      totalTimeMap += (end-start); 
     } 

     for(int i=0; i<numTests; i++){ 
      long start = System.currentTimeMillis(); 

      String[] s = new String[max]; 
      for(int j=0; j<max; j++){ 
       s[j] = "" + j; 
      } 

      long end = System.currentTimeMillis(); 
      totalTimeArray += (end-start); 
     } 

     System.out.println("Map: " + totalTimeMap); 
     System.out.println("Array: " + totalTimeArray); 
    } 

và đầu ra đã được dự kiến ​​(Mảng nhanh hơn Bản đồ):

Map: 34564 
Array: 12822 

Câu hỏi của tôi là: tại sao Bản đồ nhanh hơn Mảng khi sử dụng Groovy?

+1

Và điều này nhất quán trong nhiều lần thực thi? Chỉ là phàm. – christopher

+0

vâng. Bạn có thể đặt tối đa 10^6 hoặc 10^5 để ví dụ chạy nhanh hơn. – lfrodrigues

+2

Ngoài ra hãy chắc chắn rằng nó thực sự là một mảng; Groovy '[]' thường tạo ra một danh sách, một 'ArrayList', nó sẽ thay đổi kích thước các hình phạt. –

Trả lời

20

Khi bạn thêm chuỗi vào mảng trong Groovy, bạn đang tạo chuỗi mẫu, sau đó được chuyển đổi thành chuỗi java (sau khi tạo khuôn mẫu) vì nó phải vừa với String[]

Đối với phiên bản Map, bạn chỉ cần lưu trữ một chuỗi templated, vì vậy không đánh giá phải được thực hiện ...

mã điểm chuẩn sau:

@Grab('org.gperfutils:gbench:0.4.3-groovy-2.4') 

int max = 10000 

new groovyx.gbench.BenchmarkBuilder().run { 
    'Array' { 
     String[] s = new String[max] 
     max.times { int idx -> 
      s[idx] = Integer.toString(idx) 
     } 
    } 
    'List' { 
     def s = [] 
     max.times{ 
      s << "${it}" 
     } 
    } 
    'Map' { 
     Map m = [:] 
     max.times { 
      m[it] = "${it}" 
     } 
    } 
}.prettyPrint() 

đâu chúng ta không sử dụng GroovyStrings trong th Phương pháp Mảng, cho tôi kết quả:

* Groovy: 2.4.3 
* JVM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02, Oracle Corporation) 
    * JRE: 1.8.0_45 
    * Total Memory: 800.5 MB 
    * Maximum Memory: 1820.5 MB 
* OS: Mac OS X (10.10.3, x86_64) 

Options 
======= 
* Warm Up: Auto (- 60 sec) 
* CPU Time Measurement: On 

      user system  cpu  real 

Array 1819502 6491 1825993 1833209 
List 1697948 6533 1704481 1724448 
Map 2040521 8932 2049453 2116760 
+1

Bravo! Bản đồ: 38225 Array: 34171. Cảm ơn! – lfrodrigues

+6

Tôi đã hiểu sai 'gperfutils' là' grapefrutils'. – Will

+0

Lol, cả hai đều tuyệt vời, một cho hồ sơ, một cho bữa ăn sáng ;-) –

Các vấn đề liên quan