2011-11-04 32 views
6

Tôi hiện đang sử dụng câu lệnh chuyển đổi để xử lý các loại tin nhắn đến trong đó có 20 trường hợp khác nhau. Một số trường hợp này là các đơn đặt hàng có cường độ lớn hơn các đơn vị khác.Tối ưu hóa câu lệnh chuyển đổi Java với nhiều trường hợp?

là trình biên dịch hotspot thể tối ưu hóa trình tự kiểm tra trường hợp để tìm ra trường hợp đúng để thực hiện hay tôi nên cấu trúc mã của tôi để các trường hợp phổ biến nhất xuất hiện đầu tiên:

switch(messageType) 
{ 
    case MOST_COMMON: 
     // handle it 
     break; 

... 
    case LEAST_COMMON: 
     // handle it 
     break; 
} 

Mọi trường hợp loại trừ lẫn nhau .

Tôi có nên sử dụng mẫu chiến lược và tra cứu Bản đồ trên loại thông báo tốt hơn không?

Hiệu suất là mối quan tâm chính khi tôi xử lý hàng nghìn thư mỗi giây và đang cố gắng cắt giảm chi phí tạo đối tượng và phương thức gọi.

Rất cám ơn,

Chris

Edit: Cám ơn các con trỏ. messageType là một int với một phạm vi chặt chẽ của các giá trị vì vậy có vẻ như nó sẽ biên dịch sang bytecode "tableswitch", do đó không cần phải sắp xếp lại các trường hợp.

phần có liên quan của JVM spec là đây http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14942

+1

IIRC hầu hết các trình biên dịch xử lý các câu lệnh 'switch' trong C và C++ với các bảng tra cứu. Java có thể làm điều tương tự. Nhưng tôi có thể sai. – NullUserException

+0

bản sao có thể có của [Java: If vs. Switch] (http://stackoverflow.com/questions/1061101/java-if-vs-switch) –

+0

JIT * nên * tối ưu hóa đường dẫn trong khi thực thi. Tôi muốn hồ sơ cả hai cơ chế để xem chắc chắn. –

Trả lời

3

Trừ khi bạn chắc chắn rằng lệnh switch này đang gây ra vấn đề hiệu suất bạn, sau đó tôi sẽ đề nghị rằng bạn đang tối ưu hóa sớm. Ngoài ra, hãy xem the accepted answer to this question.

+0

Xin chào Mike, điểm chụp :) Mã này đề cập đến một vài trăm triệu sự kiện mỗi ngày làm việc và chiếm khoảng 30% chu kỳ CPU cho chương trình. Chỉ muốn có một ý kiến ​​về JIT trước khi đi sâu vào đặc tả JVM. – ChrisWhoCodes

3

Nếu các trường hợp là enum giá trị hoặc được phân phối mật độ int giá trị, sau đó mucking theo thứ tự sẽ không giúp bạn khi trình biên dịch JIT khởi động để biến tất cả thành bảng tra cứu.

Nếu bạn đang sử dụng thiết bị chuyển mạch chuỗi Java7 hoặc giá trị phân phối thưa thớt, sau đó phổ biến nhất nên đi trước vì nó biến thành một bộ phân tầng gồm các hoạt động kiểm tra và chi nhánh như if.

+0

với chuyển đổi chuỗi java7 nó sẽ chậm hơn bởi vì nó tuy nhiên biến thành tầng tầng 'nếu' như tuyên bố nó sẽ sử dụng 'bằng' trên eveluating dây – maks

+0

Hi Mike, chuyển đổi là một int với một phạm vi chặt chẽ các giá trị vì vậy tôi nghĩ rằng câu trả lời là tra cứu bảng và không cần phải sắp xếp lại các mệnh đề. – ChrisWhoCodes

+0

@maks, tôi nghĩ tôi đồng ý. Bạn đang cố gắng để chỉ cho tôi một phần của câu trả lời của tôi đó là sai hoặc chỉ nhận xét về thiết bị chuyển mạch chuỗi nói chung? –

1

Tuyên bố chuyển đổi là thực hiện tra cứu để xác định khối mã nào cần chuyển đến. Nó không phải là một loạt các kiểm tra if/else và thứ tự các khối được khai báo không có tác động đến hiệu suất. nghĩa là tất cả các giá trị đều được kiểm tra bằng nhau và cùng một lúc.

Một mã pseudo nó giống như (cho một phạm vi giá trị int nhỏ)

goto case_label[messageType.ordinal()]; 

Đối với một giá trị int lớn khoảng một cấu trúc bảng khác nhau được sử dụng. (Tôi cho rằng đó là bảng băm)

CPU có thể sử dụng dự đoán nhánh và nếu một trường hợp phổ biến hơn là những người khác, nó có thể tối ưu hóa việc thực thi động.

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