ฟังก์ชั่นจับเวลาใน R [ปิด]


36
  1. ฉันต้องการวัดเวลาที่ใช้ในการเรียกใช้ฟังก์ชันซ้ำ มีreplicate()และใช้ for-loops ที่เทียบเท่าหรือไม่ ตัวอย่างเช่น:

    system.time(replicate(1000, f()));
    system.time(for(i in 1:1000){f()});
    

    ซึ่งเป็นวิธีที่ต้องการ

  2. ในเอาต์พุตของsystem.time(), sys+userเวลา CPU จริงสำหรับการรันโปรแกรมคืออะไร? เป็นelapsedมาตรการที่ดีของการทำงานช่วงเวลาของโปรแกรมได้หรือไม่


3
เพียงเพื่อบันทึกเนื่องจากฉันสายเกินไปที่จะเปลี่ยนหลักสูตรของคำถามนี้อย่างชัดเจน: นี่เป็นปัญหาที่ฉันคิดว่าเหมาะสมที่สุดสำหรับ StackOverflow
Matt Parker

2
@ Matt ฉันยอมรับว่าคำถามเกี่ยวกับวิธีการที่โปรแกรมหนึ่งครั้งเหมาะสมกับ SO ฉันยังเห็นด้วยว่าการตีความตามตัวอักษรของคำถามนี้ (ตามที่ทำโดยหลายคำตอบ) จะวางไว้นอกหัวข้อที่นี่ในประวัติย่อ ดูเหมือนว่าจะมีความสนใจทางสถิติในการออกแบบการทดสอบเวลาและในการวิเคราะห์ผลลัพธ์ของการทดลองเช่นนั้น
whuber

คำตอบ:


19

สำหรับช่วงเวลาที่มีประสิทธิภาพของโปรแกรมโดยเฉพาะอย่างยิ่งเมื่อคุณมีความสนใจในการเปรียบเทียบโซลูชันทางเลือกคุณต้องมีการควบคุม! วิธีที่ดีคือการใส่ขั้นตอนที่คุณกำหนดเวลาไว้ในฟังก์ชั่น เรียกใช้ฟังก์ชันภายในลูปการจับเวลา เขียนโพรซีเดอร์ stub โดยการดึงโค้ดทั้งหมดออกจากฟังก์ชั่นของคุณและเพิ่งกลับมาจากมัน (แต่ทิ้งอาร์กิวเมนต์ทั้งหมดไว้) ใส่ต้นขั้วลงในลูปไทม์มิ่งของคุณและปรับเวลาใหม่ ซึ่งจะวัดค่าใช้จ่ายทั้งหมดที่เกี่ยวข้องกับการกำหนดเวลา ลบเวลา stub ออกจากเวลาโพรซีเดอร์เพื่อรับเน็ต: นี่ควรเป็นการวัดที่แม่นยำของเวลาจริงที่ต้องการ

เนื่องจากระบบในปัจจุบันส่วนใหญ่สามารถถูกขัดจังหวะได้โดยไม่ได้ตั้งใจเป็นสิ่งสำคัญที่จะต้องดำเนินการหลายครั้งเพื่อตรวจสอบความแปรปรวน แทนการทำหนึ่งในระยะยาวของวินาทีทำวิ่งประมาณวินาทีในแต่ละ มันจะช่วยให้คุณทำสิ่งนี้ได้ในการวนซ้ำทั้งหมดในครั้งเดียว ไม่เพียง แต่จะจัดการได้ง่ายกว่าเท่านั้น แต่ยังนำเสนอความสัมพันธ์เชิงลบเล็กน้อยในแต่ละอนุกรมเวลาซึ่งปรับปรุงการประมาณการจริงNmN/m

ด้วยการใช้หลักการพื้นฐานของการออกแบบการทดลองคุณสามารถควบคุมความแตกต่างได้เนื่องจากวิธีการปรับใช้รหัส (เช่นความแตกต่างระหว่าง a for loop และ replicate ()) นั่นทำให้ปัญหาของคุณหายไป


25

เกี่ยวกับสองคะแนนของคุณ:

  1. มันโวหาร ฉันชอบreplicate()ที่มันใช้งานได้
  2. ฉันมักจะมุ่งเน้นไปที่elapsedเช่นหมายเลขที่สาม

สิ่งที่ฉันมักจะทำคือ

N <- someNumber
mean(replicate( N, system.time( f(...) )[3], trimmed=0.05) )

จะได้รับการตัดแต่งค่าเฉลี่ย 90% ของ N f()ซ้ำของการโทร

(แก้ไขด้วยขอบคุณ Hadley สำหรับการจับ Thinko)


2
คุณไม่หมายถึงmean(replicate(N, system.time(f(...))[3]), trim = 0.05)เหรอ
hadley

2
หากการโทร f () ยาวก็ไม่เป็นไร อย่างไรก็ตามหากการโทร f () สั้นเกินไปค่าใช้จ่ายการโทรเวลาใด ๆ จะเพิ่มการวัดข้อผิดพลาด ด้วยการเรียกใช้ครั้งเดียวสำหรับ system.time () ผ่านการทำซ้ำหลาย ๆ ครั้งของ f () หนึ่งครั้งจะได้รับการแบ่งข้อผิดพลาดการโทรออกจนกว่าจะมีค่าที่น้อยที่สุด (และจะส่งคืนได้เร็วขึ้น)
John

@ จอห์น: ขอบคุณ แต่ฉันไม่ได้รับสิ่งที่คุณพูด ฉันยังสงสัยว่าตัวไหนดีกว่าทำซ้ำ f () ทั้งในและนอก system.time ()?
ทิม

การเรียกใช้คำสั่ง system.time () ทุกครั้งจะมีเวลาตัวแปรที่ใช้ในการโทรซึ่งทำให้เกิดข้อผิดพลาดในการวัดจำนวนหนึ่ง นี่เป็นจำนวนเล็กน้อย แต่ถ้า f () เป็นการโทรแบบสั้นมาก จากนั้นข้อผิดพลาดนี้สามารถ conflated กับเวลาที่ใช้ในการโทร f () ดังนั้นเมื่อคุณเรียกใช้ f () 1e5 ครั้งภายใน system.time () ครั้งเดียวข้อผิดพลาดจะถูกแบ่งออกเป็น 1e5 ชิ้น เมื่อคุณเรียกใช้ system.time () สำหรับทุก f () ผลกระทบอาจมีความหมายหากเวลาสำหรับ f () น้อย แน่นอนถ้าสิ่งที่คุณต้องการคือช่วงเวลาที่สัมพันธ์กันมันก็ไม่สำคัญอะไร
John

โอ้และส่วนที่สองคือมันจะเร็วกว่าเพียงแค่เรียก system.call () หนึ่งครั้ง
John

10

นอกจากนี้คุณยังสามารถเวลากับ timesteps กลับโดยSys.time; ของหลักสูตรนี้วัดวอลไทม์เวลาการคำนวณตามเวลาจริงดังนั้น รหัสตัวอย่าง:

Sys.time()->start;
replicate(N,doMeasuredComputation());
print(Sys.time()-start);

3

เกี่ยวกับตัวชี้วัดเวลาที่จะใช้ฉันไม่สามารถเพิ่มผู้เผชิญเหตุอื่นได้

เกี่ยวกับฟังก์ชั่นการใช้งานที่ผมชอบใช้? มาตรฐานจากแพคเกจ rbenchmark


1

พวกเขาทำสิ่งต่าง ๆ เวลาที่คุณต้องการทำ replicate () ส่งคืนเวกเตอร์ของผลลัพธ์ของการดำเนินการของแต่ละฟังก์ชัน ห่วงสำหรับไม่ ดังนั้นพวกเขาไม่ได้งบเทียบเท่า

นอกจากนี้เวลาหลายวิธีที่คุณต้องการทำอะไร จากนั้นคุณสามารถค้นหาวิธีที่มีประสิทธิภาพสูงสุด


mod-tip: โพสต์ส่วนที่สองเพื่อแสดงความคิดเห็นต่อคำตอบของเดิร์ค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.