Saya bermain-main dengan pemahaman daftar dan saya menemukan cuplikan kecil ini di situs lain:
return ''.join([`num` for num in xrange(loop_count)])
Saya menghabiskan beberapa menit mencoba untuk mereplikasi fungsi (dengan mengetik) sebelum menyadari `num`
bit itu merusaknya.
Apa yang dilakukan dengan menyertakan pernyataan dalam karakter tersebut? Dari apa yang saya lihat itu setara dengan str (num). Tetapi ketika saya menghitung waktunya:
return ''.join([str(num) for num in xrange(10000000)])
Dibutuhkan 4,09s sedangkan:
return ''.join([`num` for num in xrange(10000000)])
membutuhkan 2,43s.
Keduanya memberikan hasil yang identik tetapi yang satu jauh lebih lambat. Apa yang terjadi disini?
EDIT: Anehnya ... repr()
memberikan hasil yang sedikit lebih lambat dari `num`
. 2,99s vs 2,43s. Menggunakan Python 2.6 (belum mencoba 3.0).
python
list-comprehension
Dominic Bou-Samra
sumber
sumber
Jawaban:
Backticks adalah alias yang tidak digunakan lagi untuk
repr()
. Jangan menggunakannya lagi, sintaksnya telah dihapus di Python 3.0.Menggunakan backticks tampaknya lebih cepat daripada menggunakan
repr(num)
ataunum.__repr__()
dalam versi 2.x. Saya kira itu karena pencarian kamus tambahan diperlukan di namespace global (untukrepr
), atau di namespace objek (untuk__repr__
), masing-masing.Menggunakan
dis
modul membuktikan asumsi saya:def f1(a): return repr(a) def f2(a): return a.__repr__() def f3(a): return `a`
Pertunjukan pembongkaran:
>>> import dis >>> dis.dis(f1) 3 0 LOAD_GLOBAL 0 (repr) 3 LOAD_FAST 0 (a) 6 CALL_FUNCTION 1 9 RETURN_VALUE >>> dis.dis(f2) 6 0 LOAD_FAST 0 (a) 3 LOAD_ATTR 0 (__repr__) 6 CALL_FUNCTION 0 9 RETURN_VALUE >>> dis.dis(f3) 9 0 LOAD_FAST 0 (a) 3 UNARY_CONVERT 4 RETURN_VALUE
f1
melibatkan pencarian global untukrepr
,f2
pencarian atribut__repr__
, sedangkan operator backtick diimplementasikan dalam opcode terpisah. Karena tidak ada overhead untuk pencarian kamus (LOAD_GLOBAL
/LOAD_ATTR
) atau untuk pemanggilan fungsi (CALL_FUNCTION
), backticks lebih cepat.Saya kira orang-orang Python memutuskan bahwa memiliki operasi tingkat rendah yang terpisah
repr()
tidak sepadan, dan memiliki keduanyarepr()
dan backticks melanggar prinsipjadi fitur tersebut telah dihapus dengan Python 3.0.
sumber
Kutipan backtick umumnya tidak berguna dan hilang dengan Python 3.
Untuk apa nilainya, ini:
''.join(map(repr, xrange(10000000)))
sedikit lebih cepat daripada versi backtick untuk saya. Tetapi mengkhawatirkan hal ini mungkin merupakan pengoptimalan yang prematur.
sumber
timeit
hasil yang lebih cepat''.join(map(repr, xrange(0, 1000000)))
daripada untuk''.join([repr(i) for i in xrange(0, 1000000)])
(bahkan lebih buruk untuk''.join( (repr(i) for i in xrange(0, 1000000)) )
). Ini sedikit mengecewakan ;-)map
diimplementasikan di C, menggunakan loop C, yang jauh lebih cepat daripada loop Python yang dieksekusi di mesin virtual.map
tampak sangat jelas dan ringkas bagi saya, dan saya bahkan tidak tahu Python.Dugaan saya adalah itu
num
tidak menentukan metode__str__()
, jadistr()
harus melakukan pencarian kedua__repr__
.Para backticks mencari secara langsung
__repr__
. Jika itu benar, maka menggunakanrepr()
sebagai ganti backticks akan memberi Anda hasil yang sama.sumber