2010-08-24 31 views
5

thể trùng lặp:
Is there a performance difference between i++ and ++i in C++?tỷ lệ ++ a, a ++, a = a + 1 và a + = 1 về hiệu quả thực hiện trong C.Assume gcc là trình biên dịch

Về cách sử dụng sau đây, xin vui lòng đánh giá về thời gian thực hiện trong C. Trong một số cuộc phỏng vấn tôi đã được hỏi tôi sẽ sử dụng trong số các biến thể này và tại sao.

a++ 
++a 
a=a+1 
a+=1 
+4

Bạn thực sự nghĩ rằng bạn có nghĩa vụ phải trả lời dựa trên hiệu quả? Ngoài ra, tiêu đề và câu hỏi của bạn không đồng ý. Tôi đang đoán và chỉnh sửa điều này. –

+4

Đây có phải là C hoặc C++ không? Bởi vì trong C++, bạn không thể giả sử một ++ và một + = 1 là cùng một hoạt động (hoặc cái kia sẽ còn tồn tại nếu cái đầu tiên làm). –

+0

@Caleb: ... hoặc mã đó thậm chí biên dịch. – fredoverflow

Trả lời

92

Đây là những gì g++ -S sản xuất:

void irrelevant_low_level_worries() 
{ 
    int a = 0; 
// movl $0, -4(%ebp) 

    a++; 
// incl -4(%ebp) 

    ++a; 
// incl -4(%ebp) 

    a = a + 1; 
// incl -4(%ebp) 

    a += 1; 
// incl -4(%ebp) 
} 

Vì vậy, ngay cả khi không có công tắc ưu hoa, tất cả bốn báo cáo biên dịch vào mã chính xác cùng một máy.

+70

+1 cho tên hàm – Bob

+2

@NullUserException: Err, no, anh ta đã tắt tối ưu hóa. +1 –

+0

Đặt 'a' thành biến toàn cầu và sau đó nó sẽ không được tối ưu hóa. – wilhelmtell

0

Vâng, bạn có thể tranh luận rằng a++ là ngắn và đến điểm. Nó chỉ có thể tăng a một, nhưng ký hiệu được hiểu rất rõ. a=a+1 là chi tiết hơn một chút (không phải là một vấn đề lớn, trừ khi bạn có variablesWithGratuitouslyLongNames), nhưng một số có thể cho rằng nó linh hoạt hơn vì bạn có thể thay thế 1 hoặc một trong số a để thay đổi biểu thức. a+=1 có thể không linh hoạt như hai cách khác nhưng rõ ràng hơn một chút, theo nghĩa là bạn có thể thay đổi số tiền gia tăng. ++a là khác nhau từ a++ và một số sẽ tranh luận chống lại nó bởi vì nó không phải luôn luôn rõ ràng cho những người không sử dụng nó thường xuyên.

Về mặt hiệu quả, tôi nghĩ rằng các trình biên dịch hiện đại nhất sẽ tạo ra cùng một mã cho tất cả những điều này nhưng tôi có thể bị nhầm lẫn. Thực sự, bạn phải chạy mã của bạn với tất cả các biến thể và đo lường hoạt động tốt nhất.

(giả định rằng a là một số nguyên)

0

Tôi không thể hiểu tại sao cần có bất kỳ sự khác biệt trong thời gian thực hiện, nhưng chúng ta hãy chứng minh tôi sai.

a++ 

++a 

không tuy nhiên giống nhau, nhưng điều này không liên quan đến hiệu quả.

Khi nói đến hiệu suất của từng dòng, bối cảnh luôn quan trọng và việc đoán không phải là một ý tưởng hay. Thử nghiệm và đo lường tốt hơn

+1

Có, nó liên quan đến hiệu quả. Với '++ a', chúng ta chỉ cần tăng a và trả về giá trị mới. Với 'a ++', chúng ta phải lưu trữ' a' vào thanh ghi, sau đó tăng 'a', và sau đó trả về giá trị trong thanh ghi, hoặc chúng ta phải tăng' a' và trả về giá trị mới trừ '1'. Điều này rõ ràng là được tối ưu hóa nếu bạn không sử dụng giá trị trả về. – alternative

6

Bạn không thể xếp hạng thời gian thực hiện trong C, bởi vì nó không phải là mã C được thực hiện. Bạn phải lược tả mã thực thi được biên dịch với một trình biên dịch cụ thể chạy trên một máy tính cụ thể để có được một đánh giá.

Ngoài ra, việc xếp hạng một thao tác không cung cấp cho bạn thứ gì đó mà bạn thực sự có thể sử dụng. Các bộ vi xử lý Todays thực hiện một số lệnh song song, do đó hiệu quả của một phép toán dựa vào việc nó có thể được ghép nối với các lệnh trong mã xung quanh như thế nào.

Vì vậy, nếu bạn thực sự cần sử dụng hiệu suất có hiệu suất tốt nhất, bạn phải lập cấu hình mã. Nếu không (đó là khoảng 98% thời gian), bạn nên sử dụng một trong đó là dễ đọc nhất và tốt nhất truyền đạt những gì mã đang làm.

+6

Dịch: Đây là một câu hỏi ngu ngốc, mà không có câu trả lời có ý nghĩa. –

+2

@Steven Sudit: Không phải là một câu hỏi ngu ngốc, nhưng vô nghĩa và lỗi thời. Câu hỏi này dựa trên các điều kiện có liên quan 10 năm trước, nhưng văn hóa phần cứng và lập trình ngày nay tập trung hoàn toàn vào cách viết mã. – Guffa

+0

Tôi thấy quan điểm của bạn, nhưng tôi không chắc chắn tôi đồng ý. Ngay cả trong những ngày tối ưu hóa các trình biên dịch C và tốc độ xử lý kém trong phạm vi MHz thấp, câu hỏi này không có nhiều giá trị. –

0

Trong một cuộc phỏng vấn, tôi sẽ đi với hai câu trả lời:

  1. Thoạt nhìn, các mã được tạo nên rất giống nhau, đặc biệt là nếu a là một số nguyên.
  2. Nếu thời gian thực hiện chắc chắn là một vấn đề đã biết - bạn phải đo lường nó bằng cách sử dụng một số loại hồ sơ.
+0

Id sửa đổi 2) thành 2 '): Nếu thời gian thực hiện chắc chắn là một vấn đề đã biết, rất có thể vấn đề là ở nơi khác. Vì vậy, làm 2) – Tom

1

Điều này tùy thuộc vào loại a cũng như trong ngữ cảnh thực thi. Nếu a thuộc loại nguyên thủy và nếu tất cả bốn câu có cùng hiệu lực giống nhau thì tất cả các câu lệnh này phải tương đương và giống nhau về mặt hiệu quả. Tức là, trình biên dịch nên đủ thông minh để dịch chúng thành cùng một mã máy được tối ưu hóa. Cấp, đó không phải là một yêu cầu, nhưng nếu nó không phải là trường hợp với trình biên dịch của bạn thì đó là một dấu hiệu tốt để bắt đầu tìm kiếm một trình biên dịch tốt hơn.

3

Những trường hợp mà những thứ này thực sự quan trọng là rất hiếm và ít ở giữa. Hầu hết thời gian, nó không quan trọng chút nào. Trong thực tế, tôi sẵn sàng đặt cược rằng đây là trường hợp cho bạn.

Điều gì là đúng đối với một ngôn ngữ/trình biên dịch/kiến ​​trúc có thể không đúng đối với người khác. Và thực sự, thực tế là không liên quan trong bức tranh lớn hơn. Biết những điều này không làm cho bạn trở thành một lập trình viên tốt hơn.

Bạn nên nghiên cứu thuật toán, cấu trúc dữ liệu, phân tích tiệm cận, kiểu mã hóa rõ ràng và dễ đọc, mô hình lập trình, v.v. Những kỹ năng này quan trọng hơn nhiều trong việc tạo mã hiệu suất và dễ quản lý hơn là biết các chi tiết cấp thấp này.

Không tối ưu hóa sớm, mà còn, không tối ưu hóa vi mô. Tìm kiếm các tối ưu hóa hình ảnh lớn.

1

Đối với hầu hết các trình biên dịch, nó sẽ biên dịch thành cùng mã ASM.

0

Nó phụ thuộc vào ngữ cảnh và nếu chúng ta ở trong C hoặc C++. Trong C mã bạn đăng (ngoại trừ a-- :-) sẽ gây ra một trình biên dịch hiện đại hiện đại C để tạo chính xác cùng một mã. Nhưng do cơ hội rất cao, câu trả lời mong đợi là ++ là nhanh nhất và a = a + 1 chậm nhất, vì trình biên dịch cổ đại dựa vào người dùng để thực hiện tối ưu hóa như vậy.

Trong C++, nó phụ thuộc vào loại a. Khi a là một kiểu số, nó hoạt động giống như trong C, có nghĩa là một ++, a + = 1 và a = a + 1 tạo cùng một mã. Khi a là một đối tượng, nó phụ thuộc nếu bất kỳ toán tử (++, + và =) nào bị quá tải, vì sau đó toán tử quá tải của đối tượng được gọi.

Ngoài ra khi bạn làm việc trong một trường có trình biên dịch rất đặc biệt (như vi điều khiển hoặc hệ thống nhúng), các trình biên dịch này có thể hoạt động rất khác nhau trên mỗi biến thể đầu vào này.

+1

Tại sao 'a ++' nhanh hơn '++ a'? :) – fredoverflow

+1

@FredOverflow, Đúng vậy. Câu trả lời là sai. '++ a' sẽ luôn luôn nhanh nhất bằng' a ++', nhanh hơn nếu bạn cần giá trị trả về. – alternative

+0

@FredOverflow Nó phụ thuộc vào ý kiến ​​của người phỏng vấn. – Rudi

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