ການປະຕິບັດງານຂອງ Python: native NumPy loops, callbacks ແລະ conversion costs
ການທົດສອບຕົວເລກສະເພາະ CPU ທີ່ຖືກຄວບຄຸມ ຕິດຕາມຄ່າທີ່ຄືກັນຜ່ານ CPython loops, NumPy arithmetic, wrapper callback ຂອງ Python ແລະ Numba loop ທີ່ຖືກ compile.
ການທົດສອບຕົວເລກສະເພາະ CPU ທີ່ຖືກຄວບຄຸມ ຕິດຕາມຄ່າທີ່ຄືກັນຜ່ານ CPython loops, NumPy arithmetic, wrapper callback ຂອງ Python ແລະ Numba loop ທີ່ຖືກ compile. NumPy ທີ່ພ້ອມປ້ອນຂໍ້ມູນມີຄວາມໄດ້ປຽບຫຼາຍ, ໃນຂະນະທີ່ການປ່ຽນຈາກແລະກັບ Python lists ໄດ້ຫຼຸດຄວາມໄດ້ປຽບນັ້ນລົງເປັນເກືອບເທົ່າກັນ. ຕອນນີ້ອະທິບາຍເຖິງຂອບເຂດການປະຕິບັດງານ ແລະວິທີການວັດແທກຜົນລັບທີ່ແອັບພລິເຄຊັນຕ້ອງການ.
ອ່ານສະບັບລາຍລັກອັກສອນ (ພາສາອັງກິດ) ↗
ສິ່ງທີ່ວິດີໂອນີ້ກວມເອົາ
- CPython compile source ໄປສູ່ bytecode. ການເຮັດວຽກຂອງ interpreter/object ຊ້ຳໆ ແລະ typed native numeric loop ແມ່ນການຈັດການປະຕິບັດງານທີ່ແຕກຕ່າງກັນ.
- NumPy arithmetic ຕົວເລກສາມາດສົ່ງ batches ທີ່ຖືກພິມໄປສູ່ compiled operations; arithmetic loop ຍັງຄົງມີຢູ່, ແລະ views ສາມາດມີ layout ທີ່ບໍ່ຕໍ່ເນື່ອງກັນ.
- ວັດແທກການປ່ຽນ ແລະການສະແດງຜົນລັບທີ່ຕ້ອງການ. ໃນການເຮັດວຽກນີ້, ການປ່ຽນ Python lists ໄປເປັນ arrays ແລະກັບຄືນມາ ໄດ້ລຶບລ້າງຄວາມໄດ້ປຽບອັນໃຫຍ່ຫຼວງຂອງ ready-array.
- workloads ຂະໜາດນ້ອຍສາມາດມັກ Python ທຳມະດາ ເພາະຄ່າໂທ array-call ທີ່ຄົງທີ່ສຳຄັນ. comprehension ແປດຄ່າໄດ້ຊະນະການປຽບທຽບທີ່ວັດແທກນີ້.
- np.vectorize ແມ່ນ wrapper ອຳນວຍຄວາມສະດວກທີ່ເອີ້ນ Python ສຳລັບອົງປະກອບຕໍ່ໆໄປ; batch interface ຢ່າງດຽວບໍ່ໄດ້ສ້າງຕັ້ງ native numerical execution.
- compiled Python-syntax loops ກໍສາມາດໄວໄດ້ເຊັ່ນກັນ. ລວມຄ່າ cold compilation/setup ເມື່ອພວກມັນສຳຄັນຕໍ່ຜູ້ໂທ.
- native execution, CPU SIMD, multithreading ແລະ GPU backends ແມ່ນແນວຄິດທີ່ແຍກຕ່າງຫາກ. ຄຸນສົມບັດຂອງ CPU ທີ່ມີຢູ່ບໍ່ໄດ້ຕິດຕາມຄຳສັ່ງທີ່ໃຊ້ໃນການເຮັດວຽກສະເພາະ.
ບົດບັນທຶກທີ່ແປແລ້ວ
ແປຈາກຄຳບັນຍາຍຕົ້ນສະບັບພາສາອັງກິດ. ສຽງ ແລະ ຄຳບັນຍາຍທີ່ມີໃຫ້ແມ່ນຄວບຄຸມໂດຍ YouTube.
ເປັນຫຍັງ CPU ເຄື່ອງດຽວກັນຈຶ່ງສາມາດສຳເລັດໄວຂຶ້ນ?
0:00 ເຈົ້າຄິດວ່າ Python ຕ້ອງການພາສາໃໝ່ເພື່ອໃຫ້ໄວຂຶ້ນ. CPU ເຄື່ອງດຽວກັນໄດ້ run batch ຂອງພວກເຮົາໄວຂຶ້ນຫຼັງຈາກ loop ໄດ້ຍ້າຍ. ວຽກໄດ້ໄປໃສ? ເວລາໃດທີ່ຄວາມໄວຫາຍໄປ? ທາງລັດໃດທີ່ນຳ Python ກັບຄືນມາ? ນີ້ຄື The Daily Diff, ເບື້ອງຫຼັງ. ຈົ່ງຈັບຕາເບິ່ງທາງລັດນັ້ນ. CPython ແມ່ນການຈັດຕັ້ງປະຕິບັດ Python ມາດຕະຖານ.
0:17 ມັນ compile source ຂອງເຈົ້າເປັນ bytecode, ແລ້ວ run ຄຳສັ່ງເຫຼົ່ານັ້ນໃນ interpreter. NumPy ແມ່ນ library ຕົວເລກທີ່ arrays ຂອງມັນຖືຄ່າດ້ວຍ ປະເພດຂໍ້ມູນທີ່ໄດ້ປະກາດໄວ້. ການຄຳນວນທີ່ສ້າງມາໃນຕົວມັນສາມາດສົ່ງ batch ທັງໝົດໄປຫາ compiled operations. ເອົາຄ່າ floating point ໜຶ່ງລ້ານຄ່າ, ຄຳນວນກຳລັງສອງແຕ່ລະຄ່າ, ແລ້ວບວກຄ່າເດີມ. ທຸກເວີຊັນໄດ້ຮັບຄ່າທີ່ຄືກັນ ແລະຜະລິດຄຳຕອບທີ່ກົງກັນ. ຄ່າຕ່າງໆແມ່ນນ້ອຍພໍທີ່ຈະຮັກສາຄວາມແຕກຕ່າງຂອງການປັດເສດອອກຈາກການແຂ່ງຂັນ.
0:40 ໃນເຄື່ອງຈັກນີ້, comprehension ໃຊ້ເວລາປະມານສາມສິບສາມ milliseconds. NumPy ໃຊ້ເວລາໜ້ອຍກວ່າໜຶ່ງ. ທັງສອງ run ຢູ່ CPU. ນັ້ນແມ່ນຫຼັກຖານທີ່ມີປະໂຫຍດສຳລັບ workload ນີ້, ແລະ obituary ທີ່ຮ້າຍກາດສຳລັບ ພາສາການຂຽນໂປຣແກຣມ. ເລີ່ມຕົ້ນດ້ວຍ loop ທຳມະດາ.
Python loop ເຮັດວຽກຊ້ຳຫຍັງແດ່?
0:53 Python ໄດ້ຮັບຄ່າຕໍ່ໄປ, ປະຕິບັດການຄຳນວນ, ແລະ append ຄຳຕອບ. ແລ້ວມັນກໍເຮັດແບບນັ້ນອີກ. ການຄູນແມ່ນລາຄາຖືກ. ການຈັດການການຄູນຕໍ່ໄປ, ແລະການຈັດການ Python objects ອ້ອມຂ້າງມັນ, ເພີ່ມວຽກທຸກຄັ້ງ. ນີ້ແມ່ນ disassembly ຕົວຈິງຂອງຟັງຊັນທີ່ຖືກທົດສອບ. Iteration, multiplication ແລະ addition ປາກົດເປັນ bytecode instructions. ເວີຊັນແລະ interpreters ຂອງ Python ເລືອກຕ່າງກັນ.
1:14 ເວລານີ້ແມ່ນຂອງເວີຊັນທີ່ຢູ່ໃນຈໍ, ເຊິ່ງແມ່ນ Python 3.10. Python list ເກັບ references ໄປຫາ objects, ດັ່ງນັ້ນສິ່ງຂອງທີ່ແຕກຕ່າງກັນສາມາດ ແບ່ງປັນ list ດຽວກັນໄດ້. ວຽກການຄຳນວນຂອງພວກເຮົາໃຊ້ຕົວເລກຕະຫຼອດ. ມັນຈ່າຍຄ່າການຈັດການທົ່ວໄປ ໃນຂະນະທີ່ຮ້ອງຂໍການບໍລິການທີ່ຊ້ຳໆ. ຈິນຕະນາການການສັ່ງກາເຟແບບດຽວກັນໜຶ່ງລ້ານຄັ້ງ ແລະການຕື່ມແບບຟອມໃໝ່ ສຳລັບແຕ່ລະຈອກ. ເຄື່ອງກາເຟແມ່ນດີ.
1:36 ເອກະສານໄດ້ພັດທະນາວຽກງານຂອງມັນເອງ.
NumPy ຍ້າຍ loop ໄປໃສ?
1:38 NumPy ປ່ຽນສັນຍາ. array ນີ້ຖືຄ່າ floating point ຂະໜາດຄົງທີ່ດ້ວຍປະເພດທີ່ໄດ້ປະກາດໄວ້. array ຂອງພວກເຮົາແມ່ນ contiguous, ດັ່ງນັ້ນຄ່າຕ່າງໆຈຶ່ງຢູ່ຮ່ວມກັນໃນ memory. Views ສາມາດມີ layout ອື່ນໆ. operation ທາງຄະນິດສາດຮູ້ວ່າປະເພດຂໍ້ມູນໃດທີ່ມັນກຳລັງໄດ້ຮັບ. ການໂທສົ່ງ batch ໄປຫາ native operation. loop ຍັງຄົງເຂົ້າເບິ່ງຄ່າຕ່າງໆພາຍໃນ compiled code. ມັນສາມາດນຳໃຊ້ຄວາມຮູ້ກ່ຽວກັບປະເພດດັ່ງກ່າວຄືນໃໝ່ຕະຫຼອດການເຮັດວຽກນັ້ນ.
2:00 Python ຍັງຄົງເປັນຄົນທີ່ມອບວຽກໃຫ້. Itamar Turner Trauring ອະທິບາຍຄວາມແຕກຕ່າງໃນ Python Speed. Batch interfaces, native implementations ແລະ processor vector instructions ແມ່ນ ສິ່ງທີ່ແຍກຕ່າງຫາກ. ຊື່ຟັງຊັນສະໜອງຫຼັກຖານໜ້ອຍຫຼາຍ.
ໄວໝາຍເຖິງ GPU ຫຼື CPU ຫຼາຍຄໍ?
2:13 ຜົນລັບນີ້ໃຊ້ NumPy ຢູ່ CPU. GPU backend ເຊັ່ນ CuPy ເລືອກບ່ອນຢູ່ທີ່ແຕກຕ່າງກັນສຳລັບ arrays ແລະ operations. ການຊື້ GPU ຈະເຮັດໃຫ້ Python loop ທຳມະດານີ້ run ຢູ່ບ່ອນທີ່ມັນເຄີຍ run ຢູ່ແລ້ວ. CPU vector instructions ສາມາດປະມວນຜົນຫຼາຍຄ່າພ້ອມກັນໄດ້. NumPy ມີເຄື່ອງຈັກສຳລັບການເລືອກ kernels ທີ່ຮອງຮັບ. runtime ຂອງພວກເຮົາລາຍງານຄຸນສົມບັດທີ່ມີຢູ່, ແຕ່ບໍ່ໄດ້ຕິດຕາມຄຳສັ່ງຂອງ expression ນີ້. ການໃຫ້ຜົນໄດ້ຮັບທັງໝົດທີ່ວັດແທກໄດ້ກັບ vector instructions ຈະ ຂາຍຫຼັກຖານເກີນໄປ.
2:40 ລົດເຂັນຊື້ເຄື່ອງ GPU ສາມາດປິດຢູ່ໄດ້. ມີບາງສິ່ງທີ່ໜ້າພໍໃຈຢ່າງເລິກເຊິ່ງກ່ຽວກັບການແກ້ໄຂປະສິດທິພາບທີ່ຍັງຍົກເລີກການ ຊື້. ແຕ່ໜ້າເສຍດາຍ, benchmark ຍັງສືບຕໍ່.
ເວລາໃດທີ່ຄວາມໄວທີ່ໜ້າປະທັບໃຈຫາຍໄປ?
2:49 ດ້ວຍແປດຄ່າ, comprehension ຊະນະ. ການໂທຫາ array machinery ມີຄ່າໃຊ້ຈ່າຍຫຼາຍກວ່າວຽກນ້ອຍໆ. ready arrays ທີ່ໃຫຍ່ກວ່າໄດ້ນຳໜ້າ. ພວກເຮົາໃຊ້ການທົດລອງຊ້ຳໆ ແລະ process ທີ່ຖືກ warmed. Python builds ລຸ້ນໃໝ່ສາມາດປ່ຽນ crossover ໄດ້. ຈາກນັ້ນປ່ຽນສິ່ງທີ່ແອັບພລິເຄຊັນຕ້ອງການ. ເລີ່ມຕົ້ນດ້ວຍ Python list ແລະຈົບລົງດ້ວຍ Python list ໃໝ່. NumPy ຕ້ອງປ່ຽນ input ໃຫ້ເປັນ array ແລະປ່ຽນຄຳຕອບກັບຄືນເປັນ Python
3:11 objects. ຂັ້ນຕອນເຫຼົ່ານັ້ນຄວນຢູ່ໃນໃບບິນຖ້າແອັບພລິເຄຊັນຂອງທ່ານຕ້ອງການພວກມັນ. ທີ່ໜຶ່ງລ້ານຄ່າ, ເສັ້ນທາງທີ່ສົມບູນນັ້ນໃຊ້ເວລາປະມານຊາວແປດ milliseconds. comprehension ໃຊ້ເວລາປະມານຊາວແປດເຊັ່ນກັນ. ຄວາມໄດ້ປຽບອັນໃຫຍ່ຫຼວງຂອງພວກເຮົາກາຍເປັນເກືອບເທົ່າກັນ. ສ່ວນທີ່ໄວນັ້ນແມ່ນຂອງຈິງ. ຄວາມໄດ້ປຽບຂຶ້ນຢູ່ກັບການປ່ອຍໃຫ້ຂໍ້ມູນຢູ່ໃນຮູບແບບຕົວເລກຂອງມັນ.
ຂອບເຂດໃດທີ່ຄວນຢູ່ໃນ benchmark?
3:28 ຕິດຕາມຂໍ້ມູນ. ຖ້າ operation ຕໍ່ໄປຍອມຮັບ array, ໃຫ້ຮັກສາ array ນັ້ນໄວ້. ຖ້າເຈົ້າປ່ຽນລະຫວ່າງ lists ແລະ arrays ຊ້ຳໆ, ໃຫ້ວັດແທກການຂ້າມເຫຼົ່ານັ້ນ. ການຢຸດກ່ອນການສົ່ງຕໍ່ທີ່ມີລາຄາແພງໃຫ້ຕົວເລກທີ່ຖືກຕ້ອງສຳລັບຄຳຖາມທີ່ຜິດ. ການຄູນ array ນີ້ສ້າງຜົນລັບຊົ່ວຄາວ. ການບວກຄ່າເດີມສ້າງ output. native execution ຍັງຕ້ອງການ memory ແລະຍ້າຍຂໍ້ມູນ.
3:47 ບາງ operations ຍອມຮັບ output buffer, ຫຼຸດການຈັດສັນເມື່ອລະຫັດຂອງເຈົ້າສາມາດ ນຳໃຊ້ມັນຄືນໃໝ່ໄດ້ຢ່າງປອດໄພ. ເສັ້ນທີ່ສວຍງາມໜຶ່ງເສັ້ນສາມາດສັ່ງ buffers ຂະໜາດໃຫຍ່ໄດ້ຫຼາຍອັນ. Python Speed ກໍໄດ້ກ່າວເຖິງບັນຫານີ້ເຊັ່ນກັນ. allocator ແມ່ນບໍ່ສົນໃຈກັບຄວາມງາມຂອງເຈົ້າຢ່າງເຫັນໄດ້ຊັດ.
compiled Python loop ສາມາດໄວໄດ້ເຊັ່ນກັນບໍ?
4:00 ເຈົ້າຍັງສາມາດຮັກສາ loop syntax ແລະປ່ຽນ execution ຂອງມັນໄດ້. Numba ສາມາດ compile numerical Python functions ທີ່ຮອງຮັບໃຫ້ເປັນ native code. ນີ້ແມ່ນ loop ຈາກການທົດສອບຂອງພວກເຮົາດ້ວຍ compiler decorator ຂອງມັນ. ມັນຍັງຄົງເວົ້າວ່າ for. expensive interpreter path ໄດ້ປ່ຽນໄປແລ້ວ. ຫຼັງຈາກ compilation, loop ນີ້ໃຊ້ເວລາໜ້ອຍກວ່າເຄິ່ງ milliseconds ດ້ວຍ ready arrays. Compilation ເອງໃຊ້ເວລາປະມານໜຶ່ງວິນາທີໃນການ run ນີ້. ຄ່າ setup ນັ້ນຖືກຍົກເວັ້ນຈາກ repeated timings,
4:22 ດັ່ງນັ້ນວຽກນ້ອຍໆທີ່ເຮັດຄັ້ງດຽວຄວນໄດ້ຮັບການປຽບທຽບທີ່ແຕກຕ່າງກັນ. ຄູ່ມືຂອງ Numba ເອງກໍດີໃຈທີ່ຈະສະແດງ explicit loops. ການເລີ່ມຕົ້ນການຍ້າຍພາສາກ່ອນທີ່ຈະຊອກຫາ hot path ແມ່ນວິທີທີ່ຊັບຊ້ອນໃນການ ຫຼີກລ້ຽງການເປີດ profiler. ທຳອິດໃຫ້ຊອກຫາວ່າຫຍັງທີ່ໃຊ້ເວລາ. Network waits, object parsing ແລະ bulk arithmetic ຕ້ອງການການແກ້ໄຂທີ່ແຕກຕ່າງກັນ. Native array operations ຊ່ວຍໄດ້ເມື່ອການຄຳນວນແລະຂໍ້ມູນເໝາະສົມ.
4:43 ວັດແທກຜົນລັບທີ່ຜູ້ໂທຂອງເຈົ້າຕ້ອງການແທ້ໆ. ຕອນນີ້ສຳລັບທາງລັດນັ້ນ. ເຈົ້າມີ Python function ແລະຕ້ອງການໃຫ້ມັນຍອມຮັບ array. wrapper ທີ່ຊື່ວ່າ vectorize ຟັງຄືປຸ່ມປະສິດທິພາບທີ່ຫາຍໄປ. ເອກະສານຂອງມັນມີປະໂຫຍກທີ່ສຳຄັນທີ່ລໍຖ້າຢູ່.
np.vectorize ປະຕິບັດຫຍັງແທ້?
4:56 NumPy ເວົ້າວ່າ wrapper vectorize ຂອງມັນແມ່ນສະໜອງໃຫ້ເພື່ອຄວາມສະດວກສະບາຍເປັນຫຼັກ. ການຈັດຕັ້ງປະຕິບັດຂອງມັນແມ່ນເປັນ for loop ໂດຍພື້ນຖານແລ້ວ. wrapper ຍອມຮັບ batches, ແຕ່ຍັງຄົງເອີ້ນ Python function ຂອງເຈົ້າສຳລັບ ອົງປະກອບຕໍ່ໆໄປ. interface ສັ້ນລົງ. execution boundary ຍັງຄົງຫຍຸ້ງ. ເບິ່ງຄ່າດຽວກັນກັບຄືນມາຜ່ານ Python callback. ດ້ວຍ ready arrays, ເວີຊັນນີ້ໃຊ້ເວລາປະມານແປດສິບເຈັດ milliseconds. ມັນຊ້າກວ່າ comprehension ຂອງພວກເຮົາ.
5:18 wrapper broadcasting ທີ່ມີປະໂຫຍດສາມາດຮັກສາ per element work ທີ່ເຈົ້າກຳລັງ ພະຍາຍາມເອົາອອກ. ກວດສອບການຈັດຕັ້ງປະຕິບັດທີ່ຢູ່ເບື້ອງຫຼັງ batch interface, ຮັກສາຂໍ້ມູນທີ່ເຂົ້າກັນໄດ້ຢູ່ໃນຮູບແບບ ທີ່ມີປະໂຫຍດຂອງມັນ, ແລະລວມການປ່ຽນໃນການປຽບທຽບ. Native, callback ແລະ compiled loops ສາມາດເບິ່ງຄືກັນຈາກຕັ່ງຂອງຜູ້ໂທ. ຊື່ vectorize ໄດ້ສັນຍາທີ່ stopwatch ຂອງເຈົ້າບໍ່ເຄີຍເຊັນ. ຮັກສາມັນໄວ້ເມື່ອຄວາມສະດວກສະບາຍແມ່ນສິ່ງທີ່ເຈົ້າຕ້ອງການ. ສຳລັບປະສິດທິພາບ, ໃຫ້ກວດສອບ loop ທີ່ run ຢູ່.
ເຈົ້າຄວນປ່ຽນຫຍັງໃນລະຫັດຂອງເຈົ້າ?
5:41 ຄຳຕັດສິນຂອງຂ້ອຍຄື SHIP IT ສໍາລັບການ batching a measured numerical hot path. ຮັກສາ ordinary loops ເມື່ອພວກມັນເຮັດວຽກໄດ້ດີຢູ່ແລ້ວ. ກວດສອບວ່າວຽກເກີດຂຶ້ນຢູ່ໃສ ແລະຜູ້ໂທຄົນຕໍ່ໄປຕ້ອງການຫຍັງ. ກົດຕິດຕາມ, ກົດກະດິ່ງ, ແລະບອກຂ້ອຍໃນ comments ວ່າເຈົ້າຈະສະແຕມມັນ ແຕກຕ່າງກັນບໍ. ແລະນັ້ນຄື diff ສໍາລັບມື້ນີ້. ຂ້ອຍຊື່ Niko ຈາກ Axrisi. Merge ຢ່າງມີຄວາມຮັບຜິດຊອບ.
ແຫຼ່ງຂໍ້ມູນ
- Universal functions (ufunc) basics — NumPy 2.2NumPy
- The N-dimensional array — NumPy 2.2NumPy
- numpy.vectorize — convenience and performance notesNumPy
- CPU/SIMD optimizations — NumPy 2.2NumPy
- dis — Disassembler for Python bytecodePython Software Foundation
- CPython 3.10.12 list representationCPython contributors
- The limits of Python vectorization as a performance techniqueItamar Turner-Trauring / Python⇒Speed
- Performance TipsNumba
- Basics of CuPyCuPy



