Lập trình tối ưu hóa hiệu năng

1. Tổng quát
a. Sử dụng lại đối tượng
b. Lưu ý khi viết cấu trúc điều khiển(if, else, while, ...)
- Phải sắp xếp đúng thứ tự ưu tiên cho các biêu thức logic
- Xem xét vòng lặp lựa chọn có phù hợp hay không(for, while, do while)?
- Xem xét vòng lặp điều kiện có kết thúc hay không?
- Tối ưu điều kiện kiểm tra của vòng lặp for
- Xem xét việc tính toán có thể được đưa ra ngoài vòng lặp không?
- Khai báo biến tạm để tránh phải gọi hàm tính toán nhiều lần.
c. Lưu ý khi thao tác I/O với file hệ thống
- Tắt line buffering
- Sử dụng các class Reader/Writer để đọc và ghi file theo dòng
- Caching
d. Lưu ý khi thực hiện lập trình đa luồng
e. Sử dụng StringBuilder để nối xâu
f. Phải có thời gian timeout trong các giao tiếp với hệ thống ngoài
g. Tránh ghi log ra console
2. Chi tiết thực hiện
a. Sử dụng lại đối tượng
Có 2 kỹ thuật chính là: Dedicated object reuse và Object pool. Tùy theo trường hợp mà sử dụng một cách hợp lý
- Dedicated object reuse: Khi đối tượng xử lý thường xuyên một công việc lập đi lặp lại.
VD: Cần thực hiện một công việc lập đi lập lại chuyển một đối tượng kiểu Date sang kiểu String. Trong trường hợp này ta nghĩ đến việc sử dụng lại đối tượng Date Formating.
private final SimpleDateFormat dt = new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss"); 
- Object pool:
+ Trường hợp chúng ta có một loại object(ví dụ object connection kết nối với database), và nhiều tiến trình khác nhau có thể sử dụng đoạn code mà sử dụng object này.
+ Để tránh xung đột giữa các thread trong việc dùng chung object, ta có thể sử dụng synchronized block với block object. Nhưng cách này sẽ chậm hơn việc tạo mới object trên từng thread
+ Giải pháp trong trường hợp này là xây dụng object pool chứa tập các object có vai trò như nhau. Các thread khác nhau khi cần 1 object thì có thể lấy từ pool, sau khi dùng xong có thể trả lại object cho pool để các thread khác có thể sử dụng.
b. Lưu ý khi viết cấu trúc điều khiển(if, else, while, ...)
- Phải sắp xếp đúng thứ tự ưu tiên cho các biêu thức logic
Với câu lệnh
if(slowFunction() && (i>=0) && (j>i )){}
Phải chuyển thành
if((i>=0) && (j>i ) && slowFunction()){}
- Xem xét vòng lặp lựa chọn có phù hợp hay không(for, while, do while)?
Ví dụ
while(!isOptimize()){
        doOptimize();
}

Nếu trạng thái đầu là chưa optimaze thì nên chuyển thành.
do{
       doOptimize();
while(!isOptimize());
- Xem xét vòng lặp điều kiện có kết thúc hay không?
public void sillyLoop(int i)
{
        while(i!=0){
               i--;
        }
}
Nếu trường hợp i<0 vòng lặp sẽ vô hạn.
Nên chuyển thành
public void sillyLoop(int i)
{
        while(i>0){
               i--;
        }
}
- Tối ưu điều kiện kiểm tra của vòng lặp for
for(int i=0; i<str.length();i++)
nên chuyển thành
for(int i=0; len=str.length(); i<len;i++)
- Xem xét việc tính toán có thể được đưa ra ngoài vòng lặp không?
for(int i=0; i<n; i++){
double temp=Math.sin(Math.PI/5) + Math.cos(Math.PI/7);
if(check()==temp){
//
}
}

Nên chuyển thành
double temp=Math.sin(Math.PI/5) + Math.cos(Math.PI/7);
for(int i=0; i<n; i++){
if(check()==temp){
//
}
}

- Khai báo biến tạm để tránh phải gọi hàm tính toán nhiều lần.
Ví dụ:
if(max<calcScore()){
     max=calcScore();
}
Phải chuyển thành
temp=calcScore();
if(max<temp){
     max=temp;
}

c. Lưu ý khi thao tác I/O với file hệ thống
- Tắt line buffering: Khi sử dụng PrintStream để ghi dữ liệu ra file, thiết lập mặc định của PrintStream cho phép nó khi gặp ký tự xuống dòng("\n") thì sẽ thực hiện flush dữ liệu xuống file. Tuy nhiên trong trường hợp ta ghi nhiều dòng dữ liệu ngắn, việc tự động flush dữ liệu xuống file khi gặp "\n" làm giảm hiệu quả buffering.
VD: PrintStream ps=new PrintStream(bos, false);
- Sử dụng các class Reader/Writer để đọc và ghi file theo dòng
Sẽ nhanh hơn sử dụng class DataInputStream khoảng 20% và không có các vấn đề về convert byte thành character.
- Caching: Khi cần phải đọc các dòng dữ liệu trong file nhưng không theo một thức tự xác định trước, ta nên xem xét việc đọc tất cả các dòng của file trước, lưu(cache) vào vùng nhớ của chương trình trong một ArrayList hoặc Vector để tránh việc thao tác với file nhiều lần.

Không có nhận xét nào:

Đăng nhận xét