2013-09-23 68 views
6

Tôi có một vòng lặp while trong đó tôi chỉ muốn thực hiện một thao tác cụ thể một lần và một thao tác khác cho tất cả các lần chạy vòng lặp khác.C/C++ chỉ so sánh một lần

while (..) { 
    if (0 == count) { 
     // do_this 
    } else { 
     // do_that 
    } 
    count++; 
} 

Ở đây, count cần phải được so sánh với 0 chỉ một lần nhưng nó là không cần thiết so sánh trong mỗi lần chạy vòng lặp. Có cách nào khác để so sánh xảy ra chỉ một lần và một lần thành công không được gọi lại?

+0

Bạn có chắc chắn rằng lần truy cập hiệu suất có liên quan không? Viết lại mã mà không có 'if()' block _might_ sẽ nhanh hơn, nhưng nó có rõ ràng đối với các nhà phát triển như bây giờ không? –

+0

Bạn không nên quan tâm quá nhiều vì đây chính xác là loại 'if' thuật toán dự đoán nhánh của CPU xử lý hoàn hảo. –

Trả lời

18

Hoặc làm điều cho count == 0 trước khi vòng lặp, hoặc nếu đó là không thể (vì nó ở giữa những thứ khác đang được thực hiện) chỉ cần viết mã của bạn là con người có thể đọc được và bất kỳ trình biên dịch một nửa phong nha sẽ tìm ra nó cho bạn. Hoặc nó sẽ không tìm ra và nhánh dự báo trong CPU sẽ thực hiện công việc. Dù bằng cách nào thì việc tối ưu hóa nano như thế này rất có thể khiến bạn mất nhiều thời gian đọc mã hơn bạn sẽ tiết kiệm được thời gian thực hiện.

+3

+1 để đề cập đến dự đoán chi nhánh. Điều đó chắc chắn sẽ bắt đầu nếu vòng lặp có đủ lần lặp lại. Và nếu không, không cần phải bận tâm. – Angew

8
{ 
    // do_this 
} 
count = 1; /*assuming count previously started at zero*/ 
while (..) { 
    // do_that 
    count++; /*although some folk prefer ++count as it's never slower than count++*/ 
} 

là tốt hơn

+0

Bạn phải làm cong bất kỳ thứ gì với if (...) statememt, nếu không nó không giống nhau. – Arpegius

+0

Arpegius: thực sự là bạn làm; '// làm điều này' sẽ được trong niềng răng. Tôi đã sửa đổi câu trả lời. – Bathsheba

+0

cảm ơn, điều đó thật tuyệt. Nhưng nó sẽ không trông sạch sẽ khi tôi có một vòng lặp while với 'getline', ví dụ: khi tôi đang đọc một tệp và chỉ muốn thực hiện một số thao tác cho dòng đầu tiên của tệp. Trong trường hợp đó, với sơ đồ của bạn, tôi sẽ cần gọi 'getline' hai lần một lần trong 'do_this' và tại một thời điểm khác trong' while (..) ' – user13107

3

Đừng tối ưu hóa không cần thiết!

Chi phí so sánh là 1-2 chu kỳ đồng hồ và theo đề cập của Nghệ thuật, nó có thể được tối ưu hóa bởi trình biên dịch. Chi phí là hoàn toàn có thể bỏ qua khi so sánh với chi phí đọc từ một tập tin. Hiệu suất của chương trình của bạn sẽ bị ràng buộc bởi I/O anyway (hoặc bộ nhớ đọc hoặc đọc đĩa tùy thuộc vào việc các tập tin được ánh xạ trong bộ nhớ).

Trong trường hợp này, bạn nên viết mã để dễ bảo trì.

+1

Trong khi chi phí so sánh là nhỏ, chi phí của một chi nhánh nói chung là khá lớn.Không phải theo thứ tự của I/O, tất nhiên, nhưng trong một đoạn mã quan trọng về hiệu suất, bạn * không * muốn ngăn chặn đường ống. – Angew

+0

@Angew Chi phí của chi nhánh trong ví dụ cụ thể này là gần với trường hợp tối ưu cho bất kỳ yếu tố dự báo chi nhánh nào mà bạn có thể nhận được. Bạn sẽ không ngăn chặn đường ống hoặc lặp lại vòng lặp quá ít lần để tối ưu hóa toàn bộ điều này là vô nghĩa. – Art

+0

@Art Có, bạn đã nói như vậy trong câu trả lời của bạn, và tôi đã cho bạn +1 cho nó. Nhưng câu trả lời này không đề cập đến điều đó: có vẻ như để nói "ngay cả khi nó không được tối ưu hóa đi, so sánh chỉ là 1-2 chu kỳ đồng hồ." Không nói lý do tại sao nó siêu tối ưu cho dự đoán chi nhánh, điều đó nghe có vẻ nguy hiểm với tôi. – Angew