2011-11-10 43 views
6

Tôi đã cấu hình cho, khido-while vòng với một cái gì đó đơn giản:do-while là vòng lặp nhanh nhất trong php?

while ($var < 1000000) { 
    ++$var; 
} 

do { 
    ++$var; 
} while ($var < 1000000); 

for ($var = 0; $var < 1000000; ++$var) { 
    //do nothing 
} 

bằng cách so sánh microtime() trước và sau các vòng.

Vòng lặp do-while là một số lượng đáng kể vòng lặp nhanh nhất. do-while thực sự nhanh hơn trong khi gần một nửa. Tôi biết rằng chúng cho các mục đích khác nhau (trong khi kiểm tra điều kiện trước khi vòng lặp thực thi và thực hiện trong khi thực thi ít nhất một lần).

Tôi biết sự đồng thuận chung là trong khi các vòng được cau mày và làm trong khi thậm chí nhiều hơn như vậy.

Câu hỏi của tôi là lý do tại sao? Xem xét số lượng vòng lặp được sử dụng trong các ứng dụng PHP, không nên do-while được sử dụng nhiều hơn? Ngay cả với câu lệnh nếu để kiểm tra điều kiện trước khi vòng lặp thực hiện, thì hiệu suất tăng đáng kể.

Câu trả lời hiện được chấp nhận của tôi là khả năng đọc mã là nghi can.

+0

Bạn có thể đăng kết quả điểm chuẩn của mình không? – bot403

+1

Tôi chưa bao giờ thấy sự đồng thuận này khi các vòng lặp xấu. Chúng là một công cụ trong bộ công cụ PHP, giống như bất kỳ công cụ nào khác. –

+0

Ai cau mày khi đang chạy vòng? Chỉ sử dụng một nửa thời gian có vẻ như rất nhiều, nhưng bạn nên đo thời gian thực tế bạn đang tiết kiệm. Bạn đang tiết kiệm một nửa của không có gì. – martinstoeckli

Trả lời

15
  1. Tối ưu hóa vi là ác. Chúng giảm khả năng đọc cho không tăng hiệu suất có thể đo lường. Ngay cả khi ứng dụng của bạn không có vòng lặp với hàng triệu vòng lặp (mà tôi nghi ngờ) sự khác biệt vẫn không đáng kể.
  2. Sự khác biệt giữa while/do while nhỏ hơn bạn nói: http://codepad.viper-7.com/M8cgt9
  3. Để hiểu tại sao do while là nhẹ nhanh hơn, nhìn vào opcodes tạo:

    line  # * op       fetch   ext return operands 
    --------------------------------------------------------------------------------- 
    # while loop 
        3  0 > ASSIGN             !0, 0 
        4  1 > IS_SMALLER          ~1  !0, 1000000 
         2 > JMPZ              ~1, ->5 
         3 > PRE_INC             !0 
         4 > JMP              ->1 
         5 > > RETURN             1 
    # do while loop 
        3  0 > ASSIGN             !0, 0 
        4  1 > PRE_INC             !0 
         2  IS_SMALLER          ~2  !0, 1000000 
         3 > JMPNZ             ~2, ->1 
        4  > > RETURN             1 
    # for loop 
        3  0 > ASSIGN             !0, 0 
         1 > IS_SMALLER          ~1  !0, 1000000 
         2 > JMPZNZ          5   ~1, ->6 
         3 > PRE_INC             !0 
         4 > JMP              ->1 
         5 > > JMP              ->3 
         6 > > RETURN             1 
    

    Vòng lặp do while chỉ có một tuyên bố nhảy (JMPNZ), trong khi vòng lặp while cần hai (JMPZ, JMP). Vòng lặp for cần ba câu lệnh nhảy (JMPZNZ, JMP, JMP) và có logic phức tạp hơn.

+0

Tôi không nghĩ vậy. Nếu anh ta được trả tiền cho nó. Nếu anh ta thích nó. Khi nó có một triệu lần lặp thì nó có ý nghĩa. – Bytemain

+0

@Jitamaro ngay cả khi có hàng triệu lần lặp lại sự khác biệt giữa thời gian/làm-trong khi/cho hầu như luôn luôn không đáng kể so với thời gian dành công cụ trong vòng lặp. – Marcus

+0

Vòng lặp không đáng kể, tốc độ thuật toán, bộ nhớ được quan trọng hơn là – andho

1

Nếu bạn muốn có vòng lặp nhanh, bạn phải hủy đăng ký hoặc sử dụng thiết bị duff.

Bạn cũng có thể tắt cho vòng lặp (demo):

for ($var = 0; ++$var < 10;) { 
    // do nothing 
} 

Bạn cũng có thể tắt các do-while loop (demo):

$var=0; 
do { 
    echo "Hello"; 
} while (++$var < 10); 

Nhưng opcodes đều giống nhau.

Và đây là một phiên bản sửa đổi của thiết bị duff từ php.net:

If you're already using the fastest algorithms you can find (on the order of O(1),  
O(n), or O(n log n)), and you're still worried about loop speed, unroll your loops 
using e.g., Duff's Device: 

<?php 
$n = $ITERATIONS % 8; 
while ($n--) $val++; 
$n = (int)($ITERATIONS/8); 
while ($n--) { 
    $val++; 
    $val++; 
    $val++; 
    $val++; 
    $val++; 
    $val++; 
    $val++; 
    $val++; 
} 
?> 

(Đây là một hình thức sửa đổi của thiết bị gốc Duff, bởi vì PHP không hiểu cú pháp nghiêm trọng các
gốc.)

là thuật toán tương đương Đó mẫu chung:

<?php 
for ($i = 0; $i < $ITERATIONS; $i++) { 
    $val++; 
} 
?> 

$val++ can be whatever operation you need to perform ITERATIONS number of times. 

On my box, with no users, average run time across 100 samples with ITERATIONS =  
10000000 (10 million) is: 
Duff version:  7.9857 s 
Obvious version: 27.608 s 
0

Nếu bạn quan tâm đến loại điều đó, bạn có thể thấy PHPBench thú vị.

Ý kiến ​​cá nhân của tôi là bạn nên sử dụng trong khi, làm và cho các vòng mà chúng dễ đọc nhất. Tốc độ tăng 6% trên vòng lặp trống không đủ quan trọng nếu bạn dành phần lớn thời gian của mình trong cơ sở dữ liệu.

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