2010-03-28 43 views
9

Có các thủ thuật tối ưu tiêu chuẩn cho Objective-C để thực hiện nhanh hơn theo các phương thức thường xuyên "nội tuyến" như trong C++ hoặc thẻ "g ++ -fast" không?Tối ưu hóa mục tiêu-C

Chỉnh sửa: Có ai có ví dụ ngắn sử dụng SEL và IMP khi phương pháp này có hai (hoặc nhiều) số nguyên cho đầu vào không?

+0

Chủ đề này được thảo luận chi tiết ở đây: http://www.mulle-kybernetik.com/artikel/Optimization/ – codewarrior

+1

Trong một khuôn khổ cấp cao như Cocoa, hầu hết các tối ưu hóa nhỏ như thế này đều lãng phí thời gian (ngoài việc thay đổi cài đặt trình biên dịch), vì rất nhiều các lớp cơ bản đã được tối ưu hóa rất nhiều. Bạn chỉ nên tối ưu hóa nếu tiểu sử hiển thị rằng có điều gì đó đang tốn nhiều thời gian hơn. – shosti

Trả lời

12

Đây là một tối ưu hóa nhỏ có thể không thực sự xứng đáng với thời gian để triển khai, và cái mà tôi không bao giờ sử dụng cá nhân, nhưng tôi vẫn đoán là tốt. Thay vì liên tục gửi cùng một thông điệp đến cùng một đối tượng, bạn có thể bỏ qua việc gửi phương thức lặp lại bằng cách trực tiếp sử dụng phương thức triển khai thực hiện. Ví dụ, thay vì:

for (int i = 0; i < 100000000; i++) 
    [someObject messageWithInt:i]; 

Bạn có thể thử:

SEL theSelector = @selector(messageWithInt:); 
IMP theMethod = [someObject methodForSelector:theSelector]; 

for (int i = 0; i < 100000000; i++) 
    theMethod (someObject, theSelector, i); 

này có nghĩa là tra cứu phương pháp chỉ được thực hiện một lần và bạn có thể gọi phương pháp trực tiếp thông qua các trở IMP giá trị. Tất cả các thực thi phương thức Objective-C có ít nhất hai đối số, đối số đầu tiên là đối tượng nhận kiểu id, trở thành self trong thực hiện phương thức và đối số thứ hai là công cụ chọn [loại SEL] đã được sử dụng để xác định phương thức triển khai và trở thành _cmd trong quá trình triển khai phương pháp.

Cách tiếp cận này có thể nhanh chóng biến mất nếu bạn không sử dụng đúng định nghĩa chức năng “ ” (Tôi không thể nhớ thuật ngữ thích hợp). IMP là một typedef cho hàm trả về void* và mất (id,SEL,...) làm đối số. Điều này có thể làm cho nó phiền hà khi sử dụng nếu phương thức thực sự trả về một cái gì đó khác như float. Để giúp đỡ với vấn đề này, bạn có thể đúc các giá trị trở lại của -methodForSelector:, như thế này:

typedef float (*MyMethodIMP)(id,SEL,int); 

SEL theSel = @selector(messageWithInt:); 
MyMethodIMP theMethod = (MyMethodIMP)[someObject methodForSelector:theSel]; 
float result = 0.0; 

for (int i = 0; i < 100000000; i++) 
    result += theMethod (someObject, theSel, i); 

Với một số chăm sóc, bạn có thể lưu theMethod và bạn có thể sử dụng nó cho tất cả các trường hợp của một lớp học đặc biệt, không chỉ là một ví dụ, mà còn cẩn thận.

+6

Như với hầu hết các mục hiệu suất, bạn nên chạy các công cụ trên mã của bạn để xem các nút cổ chai đang ở đâu. Các mục trên là tuyệt vời ... nếu bạn cần chúng. Nếu không, nó chỉ làm cho mã khó đọc. – nall

+2

@nall: Tuyệt đối. Tôi đã làm một số điểm chuẩn cơ bản, và trong các vòng chặt chẽ như trên, bỏ qua công văn dẫn đến khoảng một nửa thời gian thực hiện ('theMethod' đã làm một số toán học cơ bản). Nếu bạn dành nhiều thời gian cho 'objc_msgSend' (hoặc bất kỳ phương thức nào được gọi là những ngày này), thì bỏ qua công văn có thể là một lựa chọn, nếu không, như bạn nói, nó sẽ có nhiều ảnh hưởng hơn là tối ưu hóa. – dreamlax

+0

Đó là một sự tối ưu hóa thực sự thú vị, nhưng sẽ không dễ dàng hơn khi chỉ tạo một hàm C thay vì lấy IMP từ một phương thức? – shosti

9

Tối ưu hóa được xử lý tốt nhất bởi trình biên dịch. Máy Mac sử dụng GCC, vì vậy cờ GCC tối ưu hóa tiêu chuẩn (-O mức) sẽ hoạt động. Trong XCode, bạn có thể đặt mức tối ưu hóa trong project settings. Nếu bạn không sử dụng GCC, hãy kiểm tra tài liệu trình biên dịch của bạn để biết cách bật tối ưu hóa.

Cập nhật: XCode 4 sử dụng phụ trợ LLVM theo mặc định. Cả hai giao diện GCC và clang đều sử dụng các cờ tối ưu hóa "-O n". Đối với GCC, n là một số nguyên từ 0 đến 3 hoặc "s" hoặc (chỉ Apple) "z". Đối với tiếng kêu, n là một số nguyên từ 0 đến 4 hoặc "s".

+0

Đó là bộ nhớ tắt nó được đặt thành [-O3] – SK9

+0

Rất cám ơn tất cả các đề xuất và thời gian của bạn! Nếu bạn sẵn sàng, bạn có thể đưa ra một ví dụ ngắn sử dụng SEL và IMP khi theMethod nhận hai (hoặc nhiều) số nguyên làm đầu vào của nó. – SK9

+0

@SpecialK: một ví dụ ngắn về * what *? Ý bạn là bình luận về câu trả lời của dreamlax? – outis