มีอะไรเร็วและดีกว่าที่จะตรวจสอบว่ามีคีย์อาร์เรย์ใน PHP หรือไม่


157

ลองพิจารณาตัวอย่างทั้งสองนี้ ...

$key = 'jim';

// example 1
if (isset($array[$key])) {
    // ...
}

// example 2    
if (array_key_exists($key, $array)) {
    // ...
}

ฉันสนใจที่จะรู้ว่าทั้งสองอย่างนี้ดีกว่าหรือไม่ ฉันเคยใช้มาก่อนเสมอ แต่เคยเห็นคนจำนวนมากใช้ตัวอย่างที่สองในเว็บไซต์นี้

ดังนั้นจะดีกว่ากัน? ได้เร็วขึ้น? เจตนาชัดเจนขึ้นหรือไม่


ฉันยังไม่ได้ใช้การวัดประสิทธิภาพใด ๆ ฉันควรถามก่อนหรือไม่
alex

4
issetจะไม่ทำตัวเหมือนarray_key_existsกันตัวอย่างรหัสที่คาดคะเนว่าจะทำให้มันทำงานเหมือนกับการประกาศหากไม่มีคีย์
หลอกลวง

เกี่ยวกับin_arrayอะไร maettig.com/1397246220
DanMan

1
@DanMan in_arrayเป็นO(n)เพราะมันตรวจสอบค่าไม่ใช่กุญแจ พวกมันเกือบจะช้าลงเสมอเว้นแต่คุณnจะเล็กมาก
Pacerier

ทำไม$array[$key] === nullล่ะ
Pacerier

คำตอบ:


237

isset()จะเร็วขึ้น array_key_exists()แต่ก็ไม่ได้เช่นเดียวกับ

array_key_exists()NULLหมดจดการตรวจสอบถ้าคีย์มีอยู่แม้ว่าค่าเป็น

ในขณะที่ isset()จะกลับมาถ้ามีอยู่ที่สำคัญและมีค่าfalseNULL


6
คุณมีทรัพยากรเฉพาะที่อ้างว่า บริษัท ผู้ออกหลักทรัพย์เร็วขึ้นหรือไม่?
Francesco Pasa

@Francesco Pasa ลองคิดดูสักหน่อย issetไม่ใช่ฟังก์ชั่นการค้นหาอาร์เรย์มันจะตรวจสอบการมีอยู่ของตัวแปรในตารางสัญลักษณ์เท่านั้นและจะไม่ซ้ำไปตามอาร์เรย์ array_key_existsในทางกลับกันจะทำซ้ำ / ค้นหาคีย์ในมิติแรกของอาร์เรย์ที่ระบุ
เรน

@ ฝนฉันค่อนข้างแน่ใจว่าarray_key_exists()จะตรวจสอบว่าคีย์อยู่ในอาร์เรย์ซึ่งหมายความว่าจะไม่ทำการค้นหาเนื่องจากเป็นตารางแฮช
Francesco Pasa

@FrancescoPasa "ค้นหาคีย์" เป็นสิ่งที่เอกสาร PHP กล่าว นอกเหนือจากนั้นฉันไม่สามารถบอกได้ว่า "ค้นหา" สำหรับพวกเขาหรือไม่นั้นหมายถึงบางสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิงกับฉัน
ฝนตก

32

หากคุณมีความสนใจในการทดสอบบางอย่างที่ฉันทำเมื่อเร็ว ๆ นี้:

https://stackoverflow.com/a/21759158/520857

สรุป:

| Method Name                              | Run time             | Difference
=========================================================================================
| NonExistant::noCheckingTest()            | 0.86004090309143     | +18491.315775911%
| NonExistant::emptyTest()                 | 0.0046701431274414   | +0.95346080503016%
| NonExistant::isnullTest()                | 0.88424181938171     | +19014.461681183%
| NonExistant::issetTest()                 | 0.0046260356903076   | Fastest
| NonExistant::arrayKeyExistsTest()        | 1.9001779556274      | +209.73055713%

สำคัญ: ระยะเวลา arrayKeyExists ก็จะพบว่ามีความผิดมาก - มันได้รับการตรวจสอบค่าไม่ได้ที่สำคัญ - ตามลิงค์ว่าสำหรับระยะเวลาในการปรับปรุง 7.1 ซึ่งเป็นมากดีกว่า (ยังจะดีกว่าในรุ่นก่อนหน้า PHP, ถ้า Populus redid ทดสอบที่.)
ToolmakerSteve

19

ความแตกต่างที่สำคัญคือisset()จะไม่ส่งคืนtrueสำหรับคีย์อาร์เรย์ที่สอดคล้องกับค่า Null ขณะที่array_key_exists()ทำ

การใช้เกณฑ์มาตรฐานขนาดเล็กแสดงว่าisset()มันเร็วขึ้น แต่อาจไม่แม่นยำอย่างสมบูรณ์


1
คุณสามารถรันเกณฑ์มาตรฐานอีกครั้งโดยใช้ "(isset ($ array [$ i]) ที่ถูกต้องมากขึ้น | | $ array [$ i] === null)"?
Tomalak

โอ้และคุณจะโพสต์ตัวบ่งชี้ประสิทธิภาพที่แตกต่างของสองตัวแปรที่แสดง? ขอบคุณ!
Tomalak

1
@ Tomalak ฉันวิ่งตามตัวอย่างที่คุณแนะนำและระบุว่า array_key_exists () เร็วกว่า isset () ด้วย | | ผู้ประกอบการ codepad.org/5qyvS93x
alex

1
ขึ้นมาจากความตาย ... แต่ฉันก็วิ่งเบนช์มาร์กอีกครั้งและทำการปรับแต่งเพื่อที่สองสำหรับลูปจะต้องเริ่มต้นมันเป็นของตัวเองและเพื่อล้างอาร์เรย์ผลลัพธ์ มันแสดงให้เห็นว่า "isset || null" กำลังเร็วขึ้น codepad.org/Np6oPvgS
KyleWpppd

3
@ Tomalak isset($array[$i]) || $array[$i] === nullไม่เข้าท่าเพราะมันจะกลับมาtrueทุกกรณี คุณจะไม่ได้รับข้อมูลเท็จ isset($array[$i]) || $array[$i] === nullโดยไม่คำนึงถึงปัจจัยการผลิต
Pacerier

10

ฉันต้องการเพิ่ม 2 เซ็นต์ของฉันสำหรับคำถามนี้เนื่องจากฉันหายไปกลางทาง

ตามที่ได้บอกไปแล้วisset()จะประเมินค่าของคีย์ดังนั้นมันจะส่งคืนfalseถ้าค่านั้นเป็นnullตำแหน่งที่array_key_exists()จะตรวจสอบเฉพาะคีย์ที่มีอยู่ในอาร์เรย์


ฉันใช้เกณฑ์มาตรฐานอย่างง่ายโดยใช้ PHP 7 ผลลัพธ์ที่แสดงคือเวลาที่ใช้ในการทำซ้ำให้เสร็จ:

$a = [null, true];

isset($a[0])                            # 0.3258841  - false
isset($a[1])                            # 0.28261614 - true
isset($a[2])                            # 0.26198816 - false

array_key_exists(0, $a)                 # 0.46202087 - true
array_key_exists(1, $a)                 # 0.43063688 - true
array_key_exists(2, $a)                 # 0.37593913 - false

isset($a[0]) || array_key_exists(0, $a) # 0.66342998 - true
isset($a[1]) || array_key_exists(1, $a) # 0.28389215 - true
isset($a[2]) || array_key_exists(2, $a) # 0.55677581 - false

array_key_isset(0, $a)                  # 1.17933798 - true
array_key_isset(1, $a)                  # 0.70253706 - true
array_key_isset(2, $a)                  # 1.01110005 - false

ฉันได้เพิ่มผลลัพธ์จากฟังก์ชั่นที่กำหนดเองนี้มาพร้อมกับเกณฑ์มาตรฐานเช่นกันเพื่อความสำเร็จ:

function array_key_isset($k, $a){
    return isset($a[$k]) || array_key_exists($k, $a);
}

เท่าที่เห็นและบอกอยู่แล้วisset()เป็นวิธีที่เร็วที่สุด nullแต่ก็สามารถกลับเท็จถ้ามีค่าเป็น สิ่งนี้อาจให้ผลลัพธ์ที่ไม่พึงประสงค์และมักจะใช้array_key_exists()หากเป็นกรณี

อย่างไรก็ตามมีวิธีออกกลางและที่ใช้isset() || array_key_exists()อยู่ รหัสนี้โดยทั่วไปจะใช้ฟังก์ชั่นที่เร็วขึ้นisset()และถ้า isset()ผลตอบแทนที่ผิดพลาดเท่านั้นจากนั้นใช้array_key_exists()ในการตรวจสอบ isset()แสดงในตารางข้างต้นเป็นเพียงแค่เร็วที่สุดเท่าที่โทรชัดถ้อยชัดคำ

ใช่มันเป็นมากกว่าการเขียนและห่อในฟังก์ชั่นจะช้าลง แต่ง่ายขึ้นมาก หากคุณต้องการสิ่งนี้เพื่อประสิทธิภาพการตรวจสอบข้อมูลขนาดใหญ่ ฯลฯ เขียนให้เต็มมิฉะนั้นหากการใช้งาน 1 ครั้งที่ค่าใช้จ่ายเล็กน้อยในฟังก์ชั่นarray_key_isset()นั้นเล็กน้อยมาก


7

กับ PHP 7 ให้เป็นไปได้ที่จะใช้Null หลอมรวมผู้ประกอบการ

ตัวดำเนินการรวมศูนย์ว่าง (??) ได้รับการเพิ่มเป็นน้ำตาลเชิงประโยคสำหรับกรณีทั่วไปที่จำเป็นต้องใช้ ternary ร่วมกับ isset () มันจะส่งกลับตัวถูกดำเนินการแรกถ้ามันมีอยู่และไม่เป็นโมฆะ; มิฉะนั้นจะส่งคืนตัวถูกดำเนินการตัวที่สอง

ดังนั้นตอนนี้คุณสามารถกำหนดค่าเริ่มต้นในกรณีที่ค่าเป็นโมฆะหรือหากไม่มีคีย์:

$var = $array[$key] ?? 'default value'

6

มีความแตกต่างจากphp.netคุณจะอ่าน:

isset () ไม่ส่งคืน TRUE สำหรับคีย์อาร์เรย์ที่สอดคล้องกับค่า NULL ขณะที่ array_key_exists () ทำ

การทดสอบที่ไม่เป็นทางการแสดงให้เห็นว่าarray_key_exists()ช้ากว่า 2.5 เท่าisset()


3

รวมisset()และis_null()ให้ประสิทธิภาพการทำงานที่ดีที่สุดกับฟังก์ชั่นอื่น ๆ เช่น: array_key_exists(), isset(), isset()+ array_key_exists(), is_null(), isset()+is_null()ปัญหาเฉพาะที่นี่คือฟังก์ชั่นไม่เพียง แต่จะกลับเท็จถ้าคีย์ไม่ได้อยู่ แต่ถึงแม้จะมีอยู่ที่สำคัญและมีค่าเป็น null

สคริปต์มาตรฐาน:

<?php
  $a = array('a' => 4, 'e' => null)

  $s = microtime(true); 
  for($i=0; $i<=100000; $i++) { 
    $t = (isset($a['a'])) && (is_null($a['a'])); //true 
    $t = (isset($a['f'])) && (is_null($a['f'])); //false
    $t = (isset($a['e'])) && (is_null($a['e']));; //false 
  } 

  $e = microtime(true); 
  echo 'isset() + is_null() : ' , ($e-$s)."<br><br>";
?>

เครดิต : http://www.zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/


1

ในฐานะ "เร็ว": ลองใช้ (เงินของฉันเปิดอยู่array_key_exists()แต่ฉันไม่สามารถลองได้ในขณะนี้)

ตามที่ "ชัดเจนในเจตนา": array_key_exists()


3
isset () เร็วขึ้นอย่างมีนัยสำคัญหากคุณไม่สนใจพฤติกรรมที่เป็นโมฆะ (ดูrandombenchmarks.com/?p=29 )
Matt Kantor

0

เห็นได้ชัดว่าตัวอย่างที่สองชัดเจนกว่าโดยเจตนาไม่มีคำถามเกี่ยวกับเรื่องนี้ หากต้องการทราบว่าตัวอย่าง # 1 ทำอะไรคุณจะต้องคุ้นเคยกับการกำหนดค่าเริ่มต้นของตัวแปร PHP - แล้วคุณจะพบว่ามันทำงานแตกต่างกันไปสำหรับค่า Null และอื่น ๆ

ซึ่งเร็วกว่า - ฉันไม่ได้ตั้งใจที่จะคาดเดา - ทำงานอย่างใดอย่างหนึ่งในวงแน่นสองสามแสนครั้งในรุ่น PHP ของคุณและคุณจะพบ :)


-2

รหัสของคุณisset($array[$i]) || $array[$i] === nullจะคืนค่าจริงในทุกกรณีแม้ว่าจะไม่มีรหัส (และให้การแจ้งเตือนดัชนีที่ไม่ได้กำหนด) เพื่อประสิทธิภาพที่ดีที่สุดสิ่งที่คุณต้องการคือif (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}


1
เวลาเท่านั้นที่$array[$i] === nullจะดำเนินการคือเมื่อ $ i อยู่ในอาร์เรย์และมีโมฆะค่า ..
Niclas ลาร์สสัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.