15/08/2015

Cái giá của việc dùng enum

Bài học về chiếc ròng rọc ở môn Vật lý lớp 7 tôi học được luôn luôn đi theo suốt cuộc đời mình: Được lợi bao nhiêu lần về lực thì thiệt bấy nhiêu lần về đường đi. Không có cái gì là hoàn mỹ cả, đồng tiền thì có hai mặt mà. Trong lập trình Android thì ENUM là công cụ rất thuận tiện khi chúng ta cần diễn đạt một tập những giá trị hữu hạn hằng số của một đối tượng, thuộc tính nào đó. Vậy thì cái giá phải trả cho nó là gì?
Bạn có thể truy xuất trang web: 
https://developer.android.com/training/articles/memory.html và bạn có thể thấy dòng sau đây: "Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android." Câu này có nghĩa là "Enums thường cần 2 lần dung lượng bộ nhớ so với hằng số tĩnh. Bạn nên tuyệt đối tránh dùng enum trong Android".
Các bạn cũng biết rằng chương trình Android sẽ được biên dịch thành dạng DEX và load vào bộ nhớ chính khi thực thi chúng. Do đó kích thước của chương trình sau khi biên dịch rất quan trọng.  
Sau đây là một thí nghiệm nhỏ. Có một chương trình sau khi biên dịch sang dạng DEX có kích thước 2556 bytes. Sau đó tác giả thêm class sử dụng hằng số như sau:
public static final int V1=1;
public static final int V2=2;
public static final int V3=3;
int function(int v){
switch (v) {
case V1:
return -1;
case V2:
return -2;
case V3:
return -3;
}
return 0;
}
 Sau khi biên dịch sang dạng DEX, kích thước chương trình là 2680 bytes, tăng 124 bytes.
Thay class trên bằng cách dùng enum:

public static enum Value{

V1,
V2,
V3
};
int function(Value v){
switch (v) {
case V1:
return -1;
case V2:
return -2;
case V3:
return -3;
}
return 0;
} 
 Khi biên dịch sang dạng DEX kích thước chương trình lúc này là 4188 bytes tăng lên 1632 bytes (13 lần so với dùng hằng kiểu int. Cứ mỗi hằng enum thì cần thêm 20bytes bộ nhớ so với dùng hằng số int). Như vậy chỉ cần dùng thêm một kiểu enum thì kích thước chương trình tăng thêm kinh khủng như vậy đó. Nếu chúng ta dùng vài chục enum trong một chương trình thì lượng bộ nhớ chúng ta phí phạm sẽ thế nào?
Câu hỏi đặt ra không dùng enum vậy có cách gì khác không? Câu trả lời là ngoài cách sử dụng hằng số tĩnh như ở trên thì Android còn cung cấp cho chúng ta công cụ @IntDef annotation. Ngoài ra nếu chúng ta quen dùng enum thì có thể chọn cách dùng ProGuard để chuyển enum thành int value trước khi biên dịch cũng được nhưng cách này hơi khó khăn.
(Bài viết tham khảo từ Internet)

14/08/2015

Củ hay quả

Tối qua ngồi bao tập, sách cho con vào lớp một, giật mình khi mở đúng trang sách:



Tại sao nó quá ấn tượng với mình vì vào khoảng năm 2005 mình từng bị một PGS-Tiến sĩ triết học chửi té khói ngay trên lớp học vì dám tranh luận với ông là phải gọi là quả lạc (quê tôi gọi là trái đậu phộng, huyện có sản lượng đậu phộng cao nhất nước) chứ không phải củ lạc. Ông miệt thị tôi không từ lời lẽ nào trước lớp học vì theo ông phải gọi là củ lạc cơ! Vì theo ông thì quả là phải do hoa thụ phấn mà thành và hoa phải ra từ nách lá. Nói đến đây mình mới vỡ lẽ ra là ông ấy chưa bao giờ nhìn thấy cánh đồng vàng tươi hoa đậu phộng (hoa lạc) ở quê tôi. Do đó tôi im lặng và không tranh luận nữa vì tôi cứ cho là mình đang chọc phải người điên vậy.
Hôm nay sau 10 năm tôi mới vở lẽ ra đâu phải riêng ông mà còn nhiều người học cao hiểu rộng vẫn nhầm lẫn củ và quả.
Ông bà xưa vậy mà giỏi vì có câu "thương nhau trái ấu cũng tròn, ghét nhau trái bồ hòn cũng méo". Vậy mà sách của nhà xuất bản giáo dục lại gọi là "củ ấu". Ấu ra từ hoa và kết quả. Đến khi chín mới rụng xuống bùn. Bà con vớt nó lên từ bùn và nhầm tưởng nó là củ nhưng thật ra nó là quả (trái).