การปั่นป่วน
calc เป็นฟังก์ชันอะซิงโครนัสที่เราต้องการทำการวิเคราะห์ (การวิเคราะห์ประสิทธิภาพ) โดยการประชุมพารามิเตอร์สุดท้ายของมันคือ callback เราใช้ calc แบบนี้:
calc (arg, (err, res) => console.log (err || res))
บางทีวิธีที่ง่ายที่สุดในการวิเคราะห์ประสิทธิภาพของฟังก์ชั่นเช่น calc คือการเพิ่มตรรกะเวลาให้กับที่ที่เราต้องวิเคราะห์:
const t0 = date.now () calc (arg, (err, res) => {const t1 = date.now () console.log (`log: เวลา: $ {t1 = t0}`) console.log (err || res)}) อย่างไรก็ตามนี่ไม่ใช่วิธีแก้ปัญหาที่นำกลับมาใช้ใหม่ได้ ทุกครั้งที่เราต้องการเวลาฟังก์ชั่นเราต้องแนะนำ T0 ในขอบเขตด้านนอกและเปลี่ยน callback เพื่อวัดและบันทึกเวลา
วิธีที่เหมาะสำหรับฉันคือการสามารถใช้เวลาเพียงแค่ห่อฟังก์ชั่นอะซิงโครนัส:
timeit (calc) (arg, (err, res) => console.log (err || res))
timeIt จะต้องสามารถทำการวิเคราะห์และบันทึกเวลาการดำเนินการสำหรับแต่ละฟังก์ชั่นอะซิงโครนัสได้ดี
โปรดทราบว่า timeIt(calc) มีลายเซ็นฟังก์ชั่นเดียวกับฟังก์ชั่น CALC ดั้งเดิมนั่นคือพวกเขายอมรับพารามิเตอร์เดียวกันและส่งคืนค่าเดียวกันมันเพิ่มคุณสมบัติให้กับ CALE (คุณลักษณะที่สามารถบันทึกเวลา)
Calc and Timeit (Calc) สามารถแทนที่ได้ตลอดเวลา
timeIt เองเป็นฟังก์ชั่นที่มีลำดับสูงกว่าเพราะยอมรับฟังก์ชั่นและส่งคืนฟังก์ชั่น ในตัวอย่างของเรามันยอมรับฟังก์ชั่น calc assynchronous และส่งคืนฟังก์ชันที่มีพารามิเตอร์เดียวกันและค่าส่งคืนเป็น Calc
ต่อไปนี้แสดงวิธีที่เราใช้ฟังก์ชัน TimeIt:
const timeit = r.curry ((รายงาน, f) => (... args) => {const t0 = date.now () const nargs = r.init (args) const callback = r.last (args) nargs.push (... args) => {const t1 = วันที่ f (... nargs)}) const timeit1 = timeit ((t, err, res) => console.log (`log: $ {err || res} ผลิตหลังจาก: $ {t}`) const calc = (x, y, z, z, callback) => settimout () console.log (err || res)) timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res))) การใช้งาน timeIt นี้ยอมรับพารามิเตอร์สองตัว:
รายงาน: ฟังก์ชั่นใช้เพื่อสร้างผลการวิเคราะห์
F: ฟังก์ชั่นอะซิงโครนัสเราต้องการทำการวิเคราะห์
timeIt1 เป็นฟังก์ชั่นที่สะดวกและใช้งานได้จริงมันใช้ console.log เพื่อบันทึกผลการวัดเวลา เรากำหนดโดยผ่านพารามิเตอร์ report ไปยังฟังก์ชัน timeIt ทั่วไปมากขึ้น
เราบรรลุเป้าหมายและตอนนี้เราสามารถสรุปฟังก์ชั่นแบบอะซิงโครนัสใน timeIt1 และเวลาที่กำหนดไว้:
timeit1 (calc) (18, 7, 3, (err, res) => console.log (err || res))
ฟังก์ชัน timeIt ทั่วไปได้รับฟังก์ชั่นการเรียกกลับ report และฟังก์ชั่นแบบอะซิงโครนัสและส่งคืนฟังก์ชันอะซิงโครนัสใหม่ ฟังก์ชั่นอะซิงโครนัสนี้มีพารามิเตอร์เดียวกันและค่าส่งคืนเป็นฟังก์ชันดั้งเดิม เราสามารถใช้สิ่งนี้:
timeit ((เวลา, ... ผลลัพธ์) => // รายงานการโทรกลับ: บันทึกเวลา, asyncFunc) (พารามิเตอร์…, (... ผลลัพธ์) => // ผลลัพธ์ของฟังก์ชัน async)
ตอนนี้เรามาดำดิ่งสู่การดำเนินการ timeIt เราสามารถสร้างฟังก์ชั่นทั่วไปเช่น timeIt1 ได้เพราะ timeIt ถูก corylated โดยใช้ R.curry
ฉันไม่ได้วางแผนที่จะหารือเกี่ยวกับ coriculization ในโพสต์นี้ แต่รหัสต่อไปนี้แสดงให้เห็นถึงการใช้งานหลักของ coriculization:
const f = r.curry ((x, y) => x + y) f (1, 10) // == 11f (1) (10) // == 11const plus1 = f (1) บวก 1 (10) // == 11
ในทางกลับกันมีปัญหาหลายประการเกี่ยวกับ TimeIt ที่นำมาใช้ในลักษณะนี้:
(... args) => {const t1 = date.now () การโทรกลับ (... args) รายงาน (t1 - t0, ... args)} นี่เป็นฟังก์ชั่นที่ไม่ระบุชื่อ (หรือที่เรียกว่าแลมบ์ดาการโทรกลับ) ซึ่งเรียกว่าหลังจากฟังก์ชั่นดั้งเดิมถูกเรียกใช้แบบอะซิงโครนัส ปัญหาหลักคือฟังก์ชั่นนี้ไม่มีกลไกในการจัดการข้อยกเว้น หาก callback มีข้อยกเว้น report จะไม่ถูกเรียก
เราสามารถเพิ่ม try / catch ให้กับฟังก์ชั่นแลม lambda นี้ได้ แต่รากของปัญหาคือ callback และ report เป็นฟังก์ชั่น void และไม่เกี่ยวข้อง timeIt มีสองความต่อเนื่อง ( report และ callback ) หากเราเพิ่งบันทึกเวลาดำเนินการภายใต้ console หรือหากเราแน่ใจว่าไม่มี report หรือ callback จะโยนข้อยกเว้นทุกอย่างก็โอเค แต่ถ้าเราต้องการดำเนินการพฤติกรรมบางอย่างตามผลการวิเคราะห์ (ที่เรียกว่าการปรับสเกลอัตโนมัติ) เราต้องเสริมสร้างและชี้แจงลำดับความต่อเนื่องในโปรแกรมของเรา
โอเคฉันหวังว่าเนื้อหาทั้งหมดของบทความนี้จะเป็นประโยชน์ต่อการศึกษาและการทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร