Apa perbedaan kinerja (jika ada) antara ketiga pendekatan ini, keduanya digunakan untuk mengubah array ke array lain?
- Menggunakan
foreach
- Menggunakan
array_map
dengan fungsi lambda / penutupan - Menggunakan
array_map
dengan fungsi / metode 'statis' - Apakah ada pendekatan lain?
Untuk memperjelas diri saya, mari kita lihat contoh-contohnya, semuanya melakukan hal yang sama - mengalikan array angka dengan 10:
$numbers = range(0, 1000);
Untuk setiap
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Peta dengan lambda
return array_map(function($number) {
return $number * 10;
}, $numbers);
Peta dengan fungsi 'statis', diteruskan sebagai referensi string
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Apakah ada pendekatan lain? Saya akan senang mendengar sebenarnya semua perbedaan antara kasus-kasus dari atas, dan setiap masukan mengapa seseorang harus digunakan daripada yang lain.
Jawaban:
FWIW, saya hanya melakukan benchmark karena poster tidak melakukannya. Berjalan di PHP 5.3.10 + XDebug.
UPDATE 2015-01-22 dibandingkan dengan jawaban mcfedr di bawah ini untuk hasil tambahan tanpa XDebug dan versi PHP yang lebih baru.
Saya mendapatkan hasil yang cukup konsisten dengan angka 1M di selusin upaya:
Andaikata kecepatan peta yang kurang bersemangat pada penutupan disebabkan oleh penutupan yang mungkin dievaluasi setiap kali, saya juga menguji seperti ini:
Tetapi hasilnya identik, mengkonfirmasi bahwa penutupan hanya dievaluasi sekali.
2014-02-02 UPDATE: dump opcodes
Berikut adalah kesedihan opcode untuk tiga panggilan balik. Pertama
useForeach()
:Kemudian
useMapClosure()
dan penutupan yang disebutnya:
maka
useMapNamed()
fungsinya:dan fungsi menamakannya panggilan,
_tenTimes()
:sumber
useMapNamed
sebenarnya lebih cepat daripadauseArray
. Pikir itu layak disebut.lap
, Anda tidak inginrange()
panggilan di atas panggilan microtime pertama? (Meskipun mungkin tidak signifikan dibandingkan dengan waktu untuk loop.)Sangat menarik untuk menjalankan benchmark ini dengan xdebug dinonaktifkan, karena xdebug menambahkan cukup banyak overhead, terutama untuk panggilan fungsi.
Ini adalah skrip FGM yang dijalankan menggunakan 5.6 Dengan xdebug
Tanpa xdebug
Di sini hanya ada perbedaan yang sangat kecil antara versi foreach dan closure.
Juga menarik untuk menambahkan versi dengan penutupan dengan a
use
Sebagai perbandingan, saya tambahkan:
Di sini kita bisa melihat itu membuat dampak pada versi penutupan, sedangkan array belum terasa berubah.
19/11/2015 Saya juga sekarang menambahkan hasil menggunakan PHP 7 dan HHVM untuk perbandingan. Kesimpulannya serupa, meskipun semuanya jauh lebih cepat.
sumber
array_map
(dan fungsinya yang terkaitarray_reduce
,array_filter
) memungkinkan Anda menulis kode yang indah. Jikaarray_map
jauh lebih lambat itu akan menjadi alasan untuk digunakanforeach
, tetapi sangat mirip, jadi saya akan menggunakan diarray_map
mana saja itu masuk akal.Ini menarik. Tetapi saya mendapatkan hasil yang berlawanan dengan kode-kode berikut yang disederhanakan dari proyek saya saat ini:
Ini data dan kode pengujian saya:
Hasilnya adalah:
Tes saya berada di lingkungan produksi LAMP tanpa xdebug. Saya mengembara xdebug akan memperlambat kinerja array_map.
sumber
array_map
;)array_map
danforeach
menggunakan Xhprof. Dan itu menarikarray_map
menghabiskan lebih banyak memori daripada `foreach`.