Không có nhiều trình biên dịch có thể làm, bởi vì nó không thể biết phương thức add
làm gì. Đây là mã được tạo ra cho phần thân của vòng lặp. Như bạn có thể thấy, nó chỉ đơn giản là gọi add
và lưu trữ kết quả.
25: iload 5
27: iload 4
29: if_icmpge 51
32: aload_3
33: iload 5
35: aaload
36: astore 6
38: aload_1
39: aload 6
41: invokevirtual #5; //Method java/math/BigInteger.add:(Ljava/math/BigInteger;)Ljava/math/BigInteger;
44: astore_1
45: iinc 5, 1
48: goto 25
Về lý thuyết, hệ thống thời gian chạy máy ảo Java có thể thông minh hơn. Ví dụ, nó có thể phát hiện rằng một đối tượng liên tục ghi đè lên một đối tượng khác chỉ được cấp phát và chỉ trao đổi hai bộ đệm phân bổ cho chúng. Tuy nhiên, như chúng ta có thể thấy bằng cách chạy chương trình sau đây với ghi nhật ký thu gom rác được bật, điều này thật đáng buồn không phải là trường hợp
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;
class Test {
public static void main(String[] args) {
ArrayList <BigInteger> nums = new ArrayList<BigInteger>();
final int NBITS = 100;
final int NVALS = 1000000;
System.out.println("Filling ArrayList");
Random r = new Random();
for (int i = 0; i < NVALS; i++)
nums.add(new BigInteger(NBITS, r));
System.out.println("Adding ArrayList values");
BigInteger A = new BigInteger("0");
for(BigInteger n : nums) {
A = A.add(n);
}
System.gc();
}
}
Xem các cuộc gọi thu gom rác trong quá trình bổ sung.
C:\tmp>java -verbose:gc Test
Filling ArrayList
[GC 16256K->10471K(62336K), 0.0257655 secs]
[GC 26727K->21107K(78592K), 0.0304749 secs]
[GC 53619K->42090K(78592K), 0.0567912 secs]
[Full GC 42090K->42090K(122304K), 0.1019642 secs]
[GC 74602K->65857K(141760K), 0.0601406 secs]
[Full GC 65857K->65853K(182144K), 0.1485418 secs]
Adding ArrayList values
[GC 117821K->77213K(195200K), 0.0381312 secs]
[GC 112746K->77245K(228288K), 0.0111372 secs]
[Full GC 77245K->137K(228288K), 0.0327287 secs]
C:\tmp>java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
Nguồn
2012-05-19 10:19:46
Nó có thể tối ưu gián tiếp theo một vài cách: ví dụ: có thể * hầu hết * phiên bản mới (ngoại trừ lần cuối) trực tiếp rất, rất ngắn và không bao giờ rời khỏi phương pháp và do đó tối ưu hóa cách phân bổ bộ nhớ của chúng. Điều này có nghĩa là * rất khó dự đoán hiệu suất của mã này. Bạn đã chuẩn bị * mã của bạn và * đã được chứng minh * rằng mã này có phải là nút cổ chai không? –
Trong trường hợp bạn cần sử dụng lớp Integer có thể thay đổi, hãy xem: [package org.apache.commons.lang.mutable] (http://commons.apache.org/lang/api-2.4/org/ apache/commons/lang/mutable/package-summary.html). – anubhava
@anubhava: Thật tốt khi biết các lớp này, nhưng tôi không thấy chúng sẽ giúp gì cho câu hỏi này. – NPE