2009-05-25 56 views
5

Tôi tò mò muốn biết về chi phí gửi tin nhắn trong Objective-C trong các tình huống khác nhau. Đặc biệt tôi muốn hướng dẫn lựa chọn thiết kế chương trình của mình vì vậy tôi không bị cám dỗ để tối ưu hóa sớm bằng cách tránh các thông báo gửi đi khi họ tạo ra một thiết kế tốt hơn.Chi phí gửi tin nhắn trong mục tiêu-C

Trường hợp trong dự án hiện tại của tôi là tôi có một lớp với các biến mẫu: offsetX và offsetY. Tôi thường muốn tuyệt đối bù đắp và tại thời điểm này tôi có dòng mã này ở khắp mọi nơi: -

int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) + 
       ((offsetY < 0.0) ? -offsetY : offsetY); 

Bây giờ nếu điều này là C++ tôi sẽ tạo ra một hàm nội tuyến đó quay trở lại giá trị cho absOffset. Ngay cả trong Java/C# tôi có thể xác định một chức năng như là cuối cùng/niêm phong và được khá chắc chắn nó sẽ được inlined.

Mục tiêu-C sẽ là: -

-(int)absOffset { 
    return ((offsetX < 0.0) ? -offsetX : offsetX) + 
      ((offsetY < 0.0) ? -offsetY : offsetY); 
} 

và tôi sẽ gọi nó là như vậy: -

int ao = [self absOffset]; 

Bây giờ, là trình biên dịch có thể nội tuyến đó? Tôi cho rằng nó ít nhất có thể sửa chữa nó thành một cuộc gọi hàm trực tiếp và tránh gửi thông điệp động (mà tôi giả định) mà mục tiêu-c phải sử dụng vì hệ thống kiểu của nó.

Ngoài ra, nhìn chung, chi phí chuyển thư trong mục tiêu-C là bao nhiêu? Nó có khác khi gọi qua 'id' so với một con trỏ tới một lớp cụ thể không?

Trả lời

14

Objective C messages are very fast. Tốc độ có thể so sánh với các cuộc gọi phương thức ảo C++, mặc dù không hoàn toàn nhanh. Tránh gửi thông báo là chắc chắn tối ưu hóa sớm. Bạn có thể không muốn làm nhiều điều trong một vòng lặp bên trong, nhưng các thuật toán bạn chọn và các yếu tố khác sẽ có một yếu tố lớn hơn nhiều về tốc độ mã của bạn. Nếu nó quá chậm, hãy sử dụng một hồ sơ và đi từ đó.

+6

+1. Điều đáng nói là mã nhắn tin được viết bằng mã lắp ráp được tối ưu hóa cao, nằm ở đây: http://opensource.apple.com/source/objc4/objc4-371.2/runtime/Messengers.subproj/ –

+1

Tôi ' m gãi đầu vào số của Mike Ash về chi phí op. Tôi chạy một phép đo tương tự của C + + gọi điện thoại ảo trên không, và thời gian tôi nhận cho mỗi gián tiếp ảo trên một bộ xử lý 3.3GHz giống như 7ns hơn 1. – Crashworks

+4

Theo liên kết đăng một cuộc gọi chức năng ảo mất 1,1ns trong khi một Mục tiêu- C công văn mất 4.9ns - chậm hơn gần 5 lần. Nhanh như người điều phối được cho là có thể vẫn là một cú đánh hoàn hảo trong hoàn cảnh thích hợp. Tôi chắc chắn đồng ý về việc tránh tối ưu hóa sớm! – fbrereto

5

Trước tiên, tôi muốn sử dụng hàm C, fabs() cho việc này. Đối với những thứ khác, việc viết các hàm đơn giản, nội tuyến, C cho các trường hợp trợ giúp nhỏ có thể hoạt động tốt. Sử dụng các phương pháp để thuận tiện hơn là hành vi kín đáo có thể là dấu hiệu của thiết kế xấu. Hiệu suất thậm chí không đi vào nó được nêu ra.

Tiếp theo, trình biên dịch không thể tối ưu hóa một cuộc gọi phương thức. Đó là một ngôn ngữ động, cuộc gọi không được giải quyết cho đến khi chạy. Các kỹ thuật Objective-C khác nhau có thể đánh bại bất kỳ nỗ lực nào của trình biên dịch để làm như vậy.

Không có sự khác biệt về thời gian chạy giữa việc gọi phương thức trên "id" so với con trỏ đã nhập - chúng đi qua chính xác cùng một cơ chế.

Cuối cùng, nếu bạn đang suy nghĩ về đặc tính hiệu suất trước khi đo bạn đã tối ưu hóa sớm. Đó không phải là để nói rằng đó là không bao giờ thích hợp, vì một số người có thể tin rằng, nhưng điều đó thường đúng. Trong trường hợp này, tôi nghĩ, nếu bạn đặt thiết kế đầu tiên, bạn sẽ có thể kết thúc với một hồ sơ hiệu suất đủ phong nha anyway. Đo lường và tối ưu hóa sau, nếu cần.

+0

Bạn có thể giải quyết một số kỹ thuật để giảm chi phí của cơ chế nhắn tin (công văn động) trong Mục tiêu-C không? – Eonil

+1

Không thực sự nhiều bạn có thể làm để giảm chi phí của nó, mỗi lần. Đó là một cơ chế cố định và đã được tối ưu hóa khá tốt rồi. Có những điều cần lưu ý, tho - chẳng hạn như không sử dụng các phương thức khi các hàm trợ giúp C thích hợp hơn (theo bài viết của tôi ở trên), tránh đấm bốc và unboxing nơi bạn có thể, và chỉ các nguyên tắc thiết kế chung tốt. Nếu chi phí của tin nhắn đi qua thực sự là một nút cổ chai (gợi ý nó rất hiếm khi là), thì có lẽ Obj-C không phải là công cụ thích hợp. Bạn có thể kết hợp C++ với Objective-C (Objective-C++) khá dễ dàng, ví dụ. – philsquared

+0

+1 cho "Sử dụng các phương pháp để thuận tiện hơn là hành vi kín đáo có thể là dấu hiệu của thiết kế kém. Hiệu suất thậm chí còn chưa thành công." Chính xác! –

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