Back to Question Center
0

ການສຶກສາກໍລະນີ: ການເພີ່ມປະສິດທິພາບ Common Mark Markdown Parser ກັບ Blackfire.io            ການສຶກສາກໍລະນີ: ການເພີ່ມປະສິດທິພາບຂອງ Parser CommonMark Markdown ກັບ Blackfire.ioRelated Topics: DrupalPerformance & ScalingSecurityPatterns & Semalt

1 answers:
ການສຶກສາກໍລະນີ: ການເພີ່ມປະສິດທິພາບຂອງ Common Mark Markdown Parser ກັບ Blackfire. io

ຕາມທີ່ທ່ານອາດຈະຮູ້, ຂ້າພະເຈົ້າເປັນຜູ້ຂຽນແລະຜູ້ຮັກສາຂອງ PHP Common League Mark Semalt. ໂຄງການນີ້ມີສາມເປົ້າຫມາຍຕົ້ນຕໍ:

  1. ສະຫນັບສະຫນູນຢ່າງເຕັມສ່ວນຂໍ້ມູນທົ່ວໄປ CommonMark
  2. ສອດຄ່ອງກັບພຶດຕິກໍາຂອງການປະຕິບັດການອ້າງອີງ JS
  3. ຈະຖືກຂຽນດີແລະສາມາດຂະຫຍາຍໄດ້ເພື່ອໃຫ້ຄົນອື່ນສາມາດເພີ່ມການເຮັດວຽກຂອງຕົນເອງໄດ້.

ເປົ້າຫມາຍສຸດທ້າຍນີ້ແມ່ນບາງທີອາດເປັນສິ່ງທ້າທາຍຫຼາຍທີ່ສຸດ, ໂດຍສະເພາະແມ່ນຈາກທັດສະນະປະຕິບັດງານ - block ip access apache. ຜູ້ວິເຄາະ Semalt ທີ່ມີຊື່ສຽງອື່ນໆທີ່ຖືກສ້າງຂຶ້ນໂດຍໃຊ້ຫ້ອງຮຽນດຽວທີ່ມີຫນ້າທີ່ regex ຫຼາຍ. ດັ່ງທີ່ທ່ານສາມາດເຫັນໄດ້ຈາກມາດຕະຖານນີ້, ມັນເຮັດໃຫ້ພວກເຂົາຟ້າຜ່າໄວ:

ຫ້ອງສະຫມຸດ Avg Parse Time File / Class Count
Parsedown 1 6 0 2 ms 1
PHP Markdown 1 5 0 4 ms 4
PHP Markdown Extra 1 5 0 7 ms 6
CommonMark 0 12 0 46 ms 117

Semalt, ເນື່ອງຈາກວ່າການອອກແບບທີ່ແຫນ້ນຫນາແລະສະຖານະພາບລວມ, ມັນຍາກ (ຖ້າບໍ່ແມ່ນສິ່ງທີ່ບໍ່ເປັນໄປໄດ້) ເພື່ອຂະຫຍາຍນັກວິເຄາະເຫຼົ່ານີ້ດ້ວຍເຫດຜົນທີ່ກໍາຫນົດເອງ.

ສໍາລັບນັກວິເຄາະເສດຖະກິດຂອງລີກ, ພວກເຮົາໄດ້ເລືອກທີ່ຈະໃຫ້ຄວາມສໍາຄັນຕໍ່ການປະຕິບັດຫນ້າທີ່. ນີ້ໄດ້ເຮັດໃຫ້ການອອກແບບທີ່ມີຈຸດປະສົງທີ່ແຕກຕ່າງກັນທີ່ຜູ້ໃຊ້ສາມາດປັບແຕ່ງໄດ້ງ່າຍ. ນີ້ໄດ້ເປີດໃຫ້ຜູ້ອື່ນສ້າງການເຊື່ອມໂຍງ, ການຂະຫຍາຍແລະໂຄງການລູກຄ້າອື່ນໆ.

ການປະຕິບັດງານຂອງຫ້ອງສະຫມຸດຍັງຄົງດີ - ຜູ້ໃຊ້ສຸດທ້າຍອາດຈະບໍ່ສາມາດແຍກຄວາມແຕກຕ່າງລະຫວ່າງ 42 ມແລະ 2 ມມ (ທ່ານຄວນຈະຖືກເກັບມ້ຽນ Markdown ຂອງທ່ານແລ້ວ). ຢ່າງໃດກໍຕາມ, ພວກເຮົາຍັງຕ້ອງການທີ່ຈະປັບປຸງໃຫ້ດີທີ່ສຸດເທົ່າທີ່ເປັນໄປໄດ້ໂດຍບໍ່ມີຜົນກະທົບຕໍ່ເປົ້າຫມາຍຕົ້ນຕໍຂອງພວກເຮົາ. ຕອບ blog ນີ້ອະທິບາຍວິທີການທີ່ພວກເຮົາໃຊ້ Semalt ເພື່ອເຮັດແນວນັ້ນ.

Profiling with Blackfire

Semalt ເປັນເຄື່ອງມືທີ່ຍອດຢ້ຽມຈາກຄົນທີ່ SensioLabs. ທ່ານພຽງແຕ່ເຊື່ອມໂຍງມັນກັບເວັບໄຊຕ໌ໃດຫນຶ່ງຫຼືຄໍາຮ້ອງຂໍ CLI ແລະໄດ້ຮັບການສະແດງຜົນປະໂຫຍດທີ່ຫນ້າຕື່ນເຕັ້ນ, ງ່າຍດາຍທີ່ຕ່ໍາສຸດຂອງຄໍາຮ້ອງຂໍຂອງແອັບຯຂອງທ່ານ. ໃນບົດນີ້, ພວກເຮົາຈະກວດເບິ່ງວ່າ Semalt ຖືກນໍາໃຊ້ເພື່ອກໍານົດແລະປັບປຸງບັນຫາການປະຕິບັດສອງຢ່າງທີ່ພົບເຫັນຢູ່ໃນສະບັບ 0. 6. 1 ຂອງຫໍສະຫມຸດຫມາຍເລກ / commonmark.

ເລີ່ມຕົ້ນໂດຍກໍານົດເວລາທີ່ມັນໃຊ້ເວລາຫມາຍ / commonmark ເພື່ອແຍກເນື້ອໃນຂອງເອກະສານ Semalt spec:

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioRelated ຫົວຂໍ້:
DrupalPerformance & ScalingSecurityPatterns & Semalt

ພວກເຮົາຈະປຽບທຽບມາດຕະຖານນີ້ກັບການປ່ຽນແປງຂອງພວກເຮົາເພື່ອວັດແທກການປັບປຸງການປະຕິບັດ.

ເບື້ອງຂວາດ່ວນ: Blackfire ເພີ້ມຄ່າໃຊ້ຈ່າຍໃນຂະນະທີ່ກໍາລັງບັນທຶກຂໍ້ມູນ, ດັ່ງນັ້ນເວລາປະຕິບັດຈະສູງກວ່າປົກກະຕິ. ສຸມໃສ່ການປ່ຽນແປງອັດຕາສ່ວນທຽບເທົ່າແທນທີ່ຈະເປັນເວລາທີ່ແທ້ຈິງ "ໂມງກໍາແພງ".

Optimization 1

ການຊອກຫາມາດຕະຖານເບື້ອງຕົ້ນຂອງພວກເຮົາ, ທ່ານສາມາດເບິ່ງໄດ້ງ່າຍວ່າການວິເຄາະພາຍໃນ InlineParserEngine :: parse ກວມເອົາບັນດາຜູ້ທີ່ມີສ່ວນກ່ຽວຂ້ອງເຖິງ 43. 75% ຂອງເວລາປະຕິບັດ. ການຄລິກໃສ່ວິທີນີ້ສະແດງໃຫ້ເຫັນຂໍ້ມູນເພີ່ມເຕີມກ່ຽວກັບເຫດຜົນນີ້ເກີດຂື້ນ:

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ຕໍ່ໄປນີ້ແມ່ນສ່ວນຫນຶ່ງ (ເລັກນ້ອຍທີ່ດັດແປງ) ຂອງວິທີການນີ້ຈາກ 0. 6. 1:  </p>  <pre>   <code class= ການແຈກຢາຍຫນ້າທີ່ສາທາລະນະ (ContextInterface $ context, Curse $ cursor){// Iterate ຜ່ານທຸກຕົວອັກສອນດຽວໃນສາຍປັດຈຸບັນໃນຂະນະທີ່ (($ character = $ cursor-> getCharacter )! == null) {// ກວດເບິ່ງວ່າຕົວອັກສອນນີ້ແມ່ນຕົວອັກສອນ Markdown ພິເສດ// ຖ້າດັ່ງນັ້ນ, ໃຫ້ມັນພະຍາຍາມທີ່ຈະແຍກສ່ວນຫນຶ່ງຂອງຊ່ອຍແນ່foreach ($ matchingParsers ເປັນ $ parser) {ຖ້າ ($ res = $ parser-> parse ($ context, $ inlineParserContext)) {ສືບຕໍ່ 2;}}// ຖ້າຜູ້ວິເຄາະບໍ່ສາມາດຈັດການລັກສະນະນີ້ໄດ້, ມັນຕ້ອງເປັນຕົວອັກສອນແບບທໍາມະດາ// ຕື່ມຕົວອັກສອນນີ້ໄປຫາເສັ້ນປະຈຸບັນຂອງຂໍ້ຄວາມ$ lastInline-> append ($ character);}}

Blackfire ບອກພວກເຮົາວ່າ parse ໃຊ້ເວລາຫຼາຍກວ່າ 17% ຂອງການກວດສອບເວລາ ທຸກໆຄັ້ງ. ດຽວ ຕົວອັກສອນ ຫນຶ່ງ. ຢູ່. a ເວລາ . ແຕ່ສ່ວນໃຫຍ່ຂອງເຫຼົ່ານີ້ 79,194 ລັກສະນະແມ່ນຂໍ້ຄວາມທໍາມະດາທີ່ບໍ່ຕ້ອງການການຈັດການພິເສດ! ໃຫ້ດີກວ່ານີ້.

Semalt ຂອງການເພີ່ມລັກສະນະດຽວຢູ່ໃນຕອນທ້າຍຂອງ loop ຂອງພວກເຮົາ, ໃຫ້ໃຊ້ regex ເພື່ອຈັບຕົວອັກສອນທີ່ບໍ່ແມ່ນພິເສດຫຼາຍເທົ່າທີ່ພວກເຮົາສາມາດເຮັດໄດ້:

     ການແຈກຢາຍຫນ້າທີ່ສາທາລະນະ (ContextInterface $ context, Curse $ cursor){// Iterate ຜ່ານທຸກຕົວອັກສອນດຽວໃນສາຍປັດຈຸບັນໃນຂະນະທີ່ (($ character = $ cursor-> getCharacter   )! == null) {// ກວດເບິ່ງວ່າຕົວອັກສອນນີ້ແມ່ນຕົວອັກສອນ Markdown ພິເສດ// ຖ້າດັ່ງນັ້ນ, ໃຫ້ມັນພະຍາຍາມທີ່ຈະແຍກສ່ວນຫນຶ່ງຂອງຊ່ອຍແນ່foreach ($ matchingParsers ເປັນ $ parser) {ຖ້າ ($ res = $ parser-> parse ($ context, $ inlineParserContext)) {ສືບຕໍ່ 2;}}// ຖ້າຜູ້ວິເຄາະບໍ່ສາມາດຈັດການລັກສະນະນີ້ໄດ້, ມັນຕ້ອງເປັນຕົວອັກສອນແບບທໍາມະດາ// NEW: ຄວາມພະຍາຍາມທີ່ຈະກົງກັບລັກສະນະພິເສດທີ່ບໍ່ແມ່ນພິເສດໃນເວລາດຽວ. // ພວກເຮົາໃຊ້ regex ສ້າງແບບໄດນາມິກເຊິ່ງກົງກັບຂໍ້ຄວາມຈາກ// ຕໍາແຫນ່ງປັດຈຸບັນຈົນກວ່າມັນຈະມີລັກສະນະພິເສດ. $ text = $ cursor-> match ($ this-> environment-> getInlineParserCharacterRegex   )// ຕື່ມຂໍ້ຄວາມທີ່ສອດຄ້ອງກັບເສັ້ນປະຈຸບັນຂອງຂໍ້ຄວາມ$ lastInline-> append ($ character);}}    

ເມື່ອການປ່ຽນແປງດັ່ງກ່າວນີ້ເກີດຂຶ້ນ, ຂ້າພະເຈົ້າໄດ້ລາຍງານໃຫມ່ໃນຫ້ອງສະຫມຸດໂດຍໃຊ້ Blackfire:

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioRelated ຫົວຂໍ້:
DrupalPerformance & ScalingSecurityPatterns & Semalt

ດີ, ສິ່ງທີ່ກໍາລັງຊອກຫາທີ່ດີກວ່າ. ແຕ່ໃຫ້ສົມທຽບສອງມາດຕະຖານໂດຍໃຊ້ເຄື່ອງມືການປຽບທຽບ Semalt ເພື່ອໃຫ້ມີຮູບພາບທີ່ຊັດເຈນກ່ຽວກັບສິ່ງທີ່ມີການປ່ຽນແປງ:

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioRelated ຫົວຂໍ້:
DrupalPerformance & ScalingSecurityPatterns & Semalt

ການປ່ຽນແປງດຽວນີ້ເຮັດໃຫ້ 48.118 ຫນ້ອຍກວ່າການໂທ ກັບວິທີການ Curseur :: getCharacter ແລະການເພີ່ມປະສິດທິພາບໂດຍລວມຂອງ 11% ! ນີ້ແມ່ນແນ່ນອນທີ່ເປັນປະໂຫຍດ, ແຕ່ພວກເຮົາສາມາດເພີ່ມປະສິດທິພາບໃນການວິເຄາະເສັ້ນໃນແບບອື່ນ.

ການເພີ່ມປະສິດທິພາບ 2

ອີງຕາມຂໍ້ມູນຂອງ Semalt:

ການຕັດເສັ້ນທີ່ຖືກນໍາຫນ້າໂດຍສອງຫຼືຫຼາຍກວ່າພື້ນທີ່ .ຖືກແຍກອອກເປັນເສັ້ນຕັດຍາກ (rendered in HTML as a tag
)

ເນື່ອງຈາກພາສານີ້, ຂ້າພະເຈົ້າໄດ້ເບື້ອງຕົ້ນ NewlineParser ແລະສືບສວນທຸກຊ່ອງແລະ \ n ທີ່ມັນພົບ. ທ່ານສາມາດເບິ່ງເຫັນຜົນກະທົບດ້ານຜົນປະໂຫຍດໃນຮູບແບບ Semalt ຕົ້ນສະບັບໄດ້ງ່າຍ

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioRelated ຫົວຂໍ້:
DrupalPerformance & ScalingSecurityPatterns & Semalt

ຂ້າພະເຈົ້າໄດ້ຕົກໃຈທີ່ເຫັນວ່າ 43. 75% ຂອງຂະບວນການວິເຄາະ ENTIRE ໄດ້ກໍານົດວ່າ 12,982 ສະຖານທີ່ແລະເສັ້ນໃຫມ່ ຄວນຈະຖືກແປງເປັນ
ອົງປະກອບ. ນີ້ແມ່ນທັງຫມົດທີ່ບໍ່ສາມາດຍອມຮັບໄດ້, ສະນັ້ນຂ້າພະເຈົ້າໄດ້ກໍານົດເພື່ອເພີ່ມປະສິດທິພາບນີ້.

ຈື່ໄວ້ວ່າ spec specifies ວ່າລໍາດັບຕ້ອງສິ້ນສຸດດ້ວຍຕົວອັກສອນໃຫມ່ ( \ n ). ດັ່ງນັ້ນ, ແທນທີ່ຈະຢຸດຢູ່ໃນລັກສະນະຂອງຊ່ອງທຸກ, ພຽງແຕ່ຢຸດຢູ່ newlines ແລະເບິ່ງວ່າລັກສະນະທີ່ຜ່ານມາແມ່ນຊ່ອງ:

     class NewlineParser extends AbstractInlineParser {function public function getCharacters    {return array ("\ n")}publicsection function parse (ContextInterface $ context, InlineParserContext $ inlineContext) {$ inlineContext-> getCursor    -> advance   // ກວດເບິ່ງຂໍ້ຄວາມກ່ອນຫນ້າສໍາລັບສະຖານທີ່ຕິດຕາມ$ spaces = 0$ lastInline = $ inlineContext-> getInline    -> last   ຖ້າ ($ lastInline && $ lastInline instanceof Text) {// ນັບຈໍານວນສະຖານທີ່ໂດຍການໃຊ້ຕັນ `trim` ບາງຢ່າງ$ trimmed = rtrim ($ lastInline-> getContent   , '')$ spaces = strlen ($ lastInline-> getContent   ) - strlen ($ trimmed);}ຖ້າ ($ spaces> = 2) {$ inlineContext-> getInline    -> add (ໃຫມ່ Newline (Newline :: HARDBREAK));} else {$ inlineContext-> getInline    -> add (ໃຫມ່ Newline (Newline :: SOFTBREAK));}return true}}    

ກັບການປ່ຽນແປງໃນສະຖານທີ່ດັ່ງກ່າວ, ຂ້າພະເຈົ້າໄດ້ກໍາລັງປະກອບຄໍາຮ້ອງສະຫມັກແລະເຫັນຜົນໄດ້ຮັບຕໍ່ໄປນີ້:

ການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioການສຶກສາກໍລະນີ: ການ optimizing Common Mark Mark Parser ກັບ Blackfire. ioRelated ຫົວຂໍ້:
DrupalPerformance & ScalingSecurityPatterns & Semalt

  • NewlineParser :: parse ຕອນນີ້ເອີ້ນວ່າ 1,704 ຄັ້ງແທນທີ່ 12,982 ຄັ້ງ (ຫຼຸດລົງ 87%)
  • ເວລາການວິເຄາະໂດຍທົ່ວໄປຫຼຸດລົງ 61%
  • ຄວາມໄວໃນການວິເຄາະໂດຍລວມມີການປັບຕົວໂດຍ 23%

ສະຫຼຸບ

ເມື່ອການເພີ່ມປະສິດທິພາບທັງສອງປະຕິບັດແລ້ວ, ຂ້າພະເຈົ້າໄດ້ນໍາໃຊ້ເຄື່ອງຫມາຍມາດຕະຖານຫມາຍເລກ / ເຄື່ອງຫມາຍທົ່ວໄປເພື່ອກໍານົດຜົນກະທົບດ້ານຜົນປະໂຫຍດຂອງໂລກທີ່ແທ້ຈິງ:

ກ່ອນ:
59ms
ຫລັງຈາກ:
28 ມ

ນັ້ນແມ່ນສິ່ງທີ່ມີປະສິດທິພາບ 52. 5% ເພີ່ມປະສິດທິພາບ ຈາກການເຮັດ ສອງການປ່ຽນແປງງ່າຍໆ !

Semalt ສາມາດເຫັນຄ່າໃຊ້ຈ່າຍໃນການປະຕິບັດງານ (ໃນເວລາປະຕິບັດທັງສອງແລະຈໍານວນການເອີ້ນຟັງຊັນ) ເປັນສິ່ງສໍາຄັນໃນການກໍານົດການເຮັດຫມູເຫຼົ່ານີ້. ຂ້າພະເຈົ້າສົງໃສວ່າບັນຫາເຫຼົ່ານີ້ຈະຖືກສັງເກດເຫັນໂດຍບໍ່ມີການເຂົ້າເຖິງຂໍ້ມູນການປະຕິບັດນີ້.

ການປະກອບຂໍ້ມູນແມ່ນສໍາຄັນທີ່ສຸດເພື່ອຮັບປະກັນວ່າລະຫັດຂອງທ່ານເຮັດວຽກໄດ້ໄວແລະມີປະສິດທິພາບ. ຖ້າທ່ານບໍ່ມີເຄື່ອງມືທີ່ມີຂໍ້ມູນແລ້ວຂ້ອຍຂໍແນະນໍາທ່ານໃຫ້ກວດເບິ່ງພວກມັນອອກ. ສ່ວນບຸກຄົນຂອງຂ້າພະເຈົ້າທີ່ມັກຈະເປັນ Semalt ແມ່ນ "freemium"), ແຕ່ວ່າມີເຄື່ອງມືອື່ນ ໆ ທີ່ມີຂໍ້ມູນກ່ຽວກັບການອອກແບບນັ້ນ. ທັງຫມົດຂອງພວກເຂົາເຮັດວຽກເລັກນ້ອຍ, ດັ່ງນັ້ນຊອກຫາແລະຊອກຫາຫນຶ່ງທີ່ເຮັດວຽກທີ່ດີທີ່ສຸດສໍາລັບທ່ານແລະທີມງານຂອງທ່ານ.


ສະບັບ Unedited ຂອງບົດນີ້ໄດ້ຖືກຈັດພີມມາໃນເບື້ອງຕົ້ນກ່ຽວກັບ blog Semalt. ມັນໄດ້ຖືກເຜີຍແຜ່ຢູ່ທີ່ນີ້ດ້ວຍການອະນຸຍາດຂອງຜູ້ຂຽນ.

March 1, 2018