2010-08-03 26 views
14

thể trùng lặp:
is “else if” faster than “switch() case” ?"nếu" so với "công tắc"

Tôi đã gặp rất nhiều tình huống thời gian gần đây, nơi tôi có điều kiện rất đơn giản và cần phải chi nhánh dòng chảy ứng dụng. Các phương tiện "đơn giản" của việc hoàn thành những gì tôi đang làm chỉ là một đồng bằng cũ if/elseif tuyên bố:

if($value == "foo") { 
    // ... 
} elseif($value == "bar") { 
    // ... 
} elseif($value == "asdf" || $value == "qwerty") { 
    // ... 
} 

... nhưng tôi cũng đang xem xét cái gì đó như:

switch($value) { 
    case "foo": 
     // ... 
     break; 
    case "bar": 
     // ... 
     break; 
    case "qwer": 
    case "asdf": 
     // ... 
} 

Điều này có vẻ một chút ít có thể đọc được, nhưng có lẽ nó hiệu quả hơn? Tuy nhiên, khi có nhiều và nhiều hơn nữa "hay" biểu thức trong điều kiện, có vẻ như câu lệnh switch là nhiều hơn nữa có thể đọc được và hữu ích:

switch($value) { 
    case "foo": 
     // ... 
     break; 
    case "bar": 
    case "baz": 
    case "sup": 
     // ... 
     break; 
    case "abc": 
    case "def": 
    case "ghi": 
     // ... 
     break; 
    case "qwer": 
    case "asdf": 
     // ... 
} 

Tôi cũng thấy tùy chọn nơi mã dòng được phân nhánh sử dụng mảng và chức năng:

function branch_xyz() {/* ... */} 
function branch_abc() {/* ... */} 
function branch_def() {/* ... */} 

$branches = array(
    "xyz"=>"branch_xyz", 
    "abc"=>"branch_abc", 
    "def"=>"branch_def" 
); 
if(isset($branches[$value])) { 
    $fname = $branches[$value]; 
    $fname(); 
} 

Tùy chọn cuối cùng này cũng có thể được phân phối trên nhiều tệp, mặc dù nó khá xấu xí.

Bạn cảm thấy có lợi thế gì nhất với sự cân bằng ít nhất về hiệu suất, khả năng đọc và dễ sử dụng?

+1

Sử dụng 'chuyển đổi 'tốt hơn trong loại tình huống bạn đã chỉ định. – Sarfraz

+2

Hiệu suất thậm chí không thực sự ảnh hưởng đến nó. Viết mã có thể đọc trước, sau đó lập hồ sơ và tối ưu hóa khi cần thiết sau đó. –

+0

Nhân bản một bản sao, v.v. http://stackoverflow.com/questions/3387758/java-case-statment-or-if-statement-efficiency-perspective –

Trả lời

27

Cá nhân, tôi thấy công tắc có thể đọc được nhiều hơn. Đây là lý do:

if ($foo == 'bar') { 
} elseif ($foo == 'baz') { 
} elseif ($foo == 'buz') { 
} elseif ($fou == 'haz') { 
} 

Bị ngưng như vậy, bạn có thể dễ dàng xem chuyến đi lên (có thể là lỗi đánh máy hoặc khác biệt trung thực). Nhưng với một chuyển đổi, bạn biết những gì đã ngầm có nghĩa là:

switch ($foo) { 
    case 'bar': 
     break; 
    case 'baz': 
     break; 
    case 'buz': 
     break; 
    case 'haz': 
     break; 
} 

Thêm vào đó, đó là dễ dàng hơn để đọc:

if ($foo == 'bar' || $foo == 'baz' || $foo == 'bat' || $foo == 'buz') { 
} 

hoặc

case 'bar': 
case 'baz': 
case 'bat': 
case 'buz': 
    break; 

Từ một quan điểm hiệu suất ... Vâng , đừng lo lắng về hiệu suất. Trừ khi bạn đang làm một vài nghìn trong số họ trong vòng lặp chặt chẽ, bạn thậm chí sẽ không thể nói sự khác biệt (sự khác biệt có thể sẽ nằm trong phạm vi vi giây, nếu không thấp hơn).

Tìm phương pháp mà bạn thấy dễ đọc nhất. Đó là phần quan trọng. Đừng cố tối ưu hóa vi mô. Hãy nhớ rằng, Premature Optimization Is The Root Of All Evil ...

+1

Hãy cẩn thận khi chuyển đổi sẽ cho bạn ** false ** false và false dương tính do [so sánh lỏng lẻo] (http://stackoverflow.com/q/3525614/632951). Ở đây, 'switch' là một mã nguồn và lệnh cấm bảo mật ipso facto. Sử dụng các phím mảng thay thế. – Pacerier

+0

@Pacerier, tại sao chuyển đổi là lệnh cấm an toàn? –

+3

@ ryabenko-pro, So sánh lỏng lẻo sẽ cung cấp cho bạn các lỗi tinh tế: 'chuyển đổi (0) {trường hợp null: echo 'null'; phá vỡ; mặc định: echo 'not null';} ' – Pacerier

1

Chuyển đổi cho người đọc sau biết rằng bạn đang phân nhánh dựa trên giá trị của một giá trị duy nhất mà họ sẽ phải ngụ ý bằng cách xem xét tất cả các điều kiện. Vì vậy, tôi muốn chuyển đổi cho rõ ràng

44

Tôi biết, tối ưu hóa vi mô là xấu.Nhưng tò mò như tôi, tôi đã làm một chuẩn mực ít sử dụng kịch bản này:

<?php 
$numof = 100000; 
$file = fopen('benchmark.php', 'w'); 
if (!$file) die('file error'); 
fwrite($file, '<pre><?php' . "\n" . 'echo $i = $_GET[\'i\'], "\n";' . "\n"); 

fwrite($file, 
'$start = microtime(true); 
if ($i == 0) {}' . "\n"); 
for ($i = 1; $i < $numof; ++$i) { 
    fwrite($file, 'elseif($i == '.$i.') {}'. "\n"); 
} 
fwrite($file, 
'echo \'elseif took: \', microtime(true) - $start, "\n";' . "\n"); 

fwrite($file, 
'$start = microtime(true); 
switch($i) {' . "\n"); 
for ($i = 1; $i < $numof; ++$i) { 
    fwrite($file, 'case '.$i.': break;'. "\n"); 
} 
fwrite($file, 
'} 
echo \'switch took: \', microtime(true) - $start, "\n";' . "\n"); 

Kết quả dữ liệu (ví numof = 100000):

i: 0 
elseif took: 6.2942504882812E-5 
switch took: 3.504753112793E-5 

i: 10 
elseif took: 6.4849853515625E-5 
switch took: 4.3869018554688E-5 

i: 100 
elseif took: 0.00014805793762207 
switch took: 0.00011801719665527 

i: 1000 
elseif took: 0.00069785118103027 
switch took: 0.00098896026611328 

i: 10000 
elseif took: 0.0059938430786133 
switch took: 0.0074150562286377 

i: 100000 (first non-existing offset) 
elseif took: 0.043318033218384 
switch took: 0.075783014297485 

đã chạy kịch bản trên máy tính của cửa sổ cũ và chậm chạp của tôi với PHP 5.3.1 hoặc 5.3.2, dunno phải biết.

+10

+1 để thực hiện điều gì đó để thực sự cố gắng đo lường sự khác biệt về hiệu suất để đưa ra câu trả lời hợp lệ cho những gì câu hỏi yêu cầu. – Kmeixner

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