MATLAB OOP ช้าหรือฉันทำอะไรผิดหรือเปล่า?


144

ผมทดลองกับMATLAB OOPเป็นจุดเริ่มต้นที่ผมเลียนแบบของฉัน c ++ 's เรียน Logger และฉันวางฟังก์ชั่นผู้ช่วยสตริงของฉันทั้งหมดในชั้นเรียน String คิดว่ามันจะดีที่จะสามารถที่จะทำสิ่งที่ชอบa + b, a == b, a.find( b )แทนstrcat( a b ), strcmp( a, b ), ดึงองค์ประกอบแรกของstrfind( a, b )ฯลฯ

ปัญหา: การชะลอตัว

ฉันใช้สิ่งต่าง ๆ ข้างต้นเพื่อใช้งานและสังเกตเห็นการชะลอตัวที่รุนแรงในทันที ฉันทำผิดหรือเปล่า (ซึ่งเป็นไปได้อย่างแน่นอนเนื่องจากฉันมีประสบการณ์ค่อนข้าง จำกัด MATLAB) หรือ OOP ของ MATLAB เพิ่งแนะนำค่าใช้จ่ายจำนวนมากหรือไม่?

กรณีทดสอบของฉัน

นี่คือการทดสอบง่ายๆที่ฉันทำกับสตริงโดยทั่วไปเพียงแค่ต่อท้ายสตริงและนำส่วนที่ต่อท้ายออกมาอีกครั้ง:

หมายเหตุ: อย่าเขียนคลาส String อย่างนี้ในรหัสจริง! Matlab มีstringประเภทอาเรย์ดั้งเดิมแล้วและคุณควรใช้มันแทน

classdef String < handle
  ....
  properties
    stringobj = '';
  end
  function o = plus( o, b )
    o.stringobj = [ o.stringobj b ];
  end
  function n = Length( o )
    n = length( o.stringobj );
  end
  function o = SetLength( o, n )
    o.stringobj = o.stringobj( 1 : n );
  end
end

function atest( a, b ) %plain functions
  n = length( a );
  a = [ a b ];
  a = a( 1 : n );

function btest( a, b ) %OOP
  n = a.Length();
  a = a + b;
  a.SetLength( n );

function RunProfilerLoop( nLoop, fun, varargin )
  profile on;
  for i = 1 : nLoop
    fun( varargin{ : } );
  end
  profile off;
  profile report;

a = 'test';
aString = String( 'test' );
RunProfilerLoop( 1000, @(x,y)atest(x,y), a, 'appendme' );
RunProfilerLoop( 1000, @(x,y)btest(x,y), aString, 'appendme' );

ผลที่ได้

เวลาทั้งหมดในหน่วยวินาทีสำหรับการวนซ้ำ 1,000 ครั้ง:

btest 0.550 (พร้อมสตริง SetLength 0.138, String.plus 0.065, String.Length 0.057)

อย่างน้อย 0.015

ผลลัพธ์สำหรับระบบ logger ก็เช่นกัน: 0.1 วินาทีสำหรับการโทร 1,000 ครั้งfrpintf( 1, 'test\n' ), 7 (!) วินาทีสำหรับการโทร 1,000 ครั้งไปยังระบบของฉันเมื่อใช้คลาส String ภายใน (ตกลงมันมีตรรกะมากกว่านั้นมาก แต่เปรียบเทียบกับ C ++: ค่าใช้จ่ายของระบบของฉันที่ใช้std::string( "blah" )และstd::coutที่ด้านเอาท์พุท vs ที่ราบstd::cout << "blah"อยู่ในลำดับ 1 มิลลิวินาที)

เป็นค่าใช้จ่ายเมื่อค้นหาฟังก์ชัน class / package หรือไม่

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

function n = atest( x, y )
  n = ctest( x, y ); % ctest is in matlab path

function n = btest( x, y )
  n = util.ctest( x, y ); % ctest is in +util directory, parent directory is in path

ผลลัพธ์รวบรวมแบบเดียวกับด้านบน:

อย่างน้อย 0.004 วินาที, 0.001 วินาทีใน ctest

btest 0.060 วินาที, 0.014 วินาทีใน util.ctest

ดังนั้นค่าใช้จ่ายทั้งหมดนี้มาจากการใช้เวลา MATLAB เพื่อค้นหาคำจำกัดความสำหรับการใช้งาน OOP ในขณะที่ค่าใช้จ่ายนี้ไม่ได้มีไว้สำหรับฟังก์ชั่นที่อยู่ในเส้นทางโดยตรงหรือไม่


5
ขอบคุณสำหรับคำถามนี้! การปฏิบัติงานของกอง Matlab (OOP / ปิด) ได้ทุกข์ฉันสำหรับปีที่ผ่านมาเห็นstackoverflow.com/questions/1446281/matlabs-garbage-collector ฉันอยากรู้จริงๆว่า MatlabDoug / Loren / MikeKatz จะตอบกระทู้ของคุณอย่างไร
มิคาอิล

1
^ นั่นคือการอ่านที่น่าสนใจ
stijn

1
@ MatlabDoug: บางทีเพื่อนร่วมงานของคุณ Mike Karr สามารถแสดงความคิดเห็น OP?
Mikhail

4
ผู้อ่านควรตรวจสอบโพสต์บล็อกล่าสุดนี้ (โดย Dave Foti) พูดคุยเกี่ยวกับประสิทธิภาพของ OOP ในรุ่น R2012a ล่าสุด: พิจารณาประสิทธิภาพในการใช้งาน Object-Oriented MATLAB Code
Amro

1
ตัวอย่างง่ายๆของความไวต่อโครงสร้างโค้ดที่การเรียกใช้เมธอดขององค์ประกอบย่อยถูกนำออกจากลูป for i = 1:this.get_n_quantities() if(strcmp(id,this.get_quantity_rlz(i).get_id())) ix = i; end endใช้เวลา 2.2 วินาทีในขณะที่nq = this.get_n_quantities(); a = this.get_quantity_realizations(); for i = 1:nq c = a{i}; if(strcmp(id,c.get_id())) ix = i; end endใช้เวลา 0.01 คำสั่งของแม็กสองคำสั่ง
Jose Ospina

คำตอบ:


223

ฉันทำงานกับ OO MATLAB มาระยะหนึ่งแล้วก็พบปัญหาด้านประสิทธิภาพที่คล้ายกัน

คำตอบสั้น ๆ คือ: ใช่ OOP ของ MATLAB ค่อนข้างช้า มีวิธีการเรียกใช้อย่างมีนัยสำคัญสูงกว่าภาษา OO หลักและไม่มีอะไรที่คุณสามารถทำได้ เหตุผลส่วนหนึ่งอาจเป็นไปได้ว่าสำนวน MATLAB ใช้รหัส "vectorized" เพื่อลดจำนวนการเรียกใช้เมธอดและค่าใช้จ่ายต่อการโทรไม่สำคัญ

ฉันเปรียบเทียบประสิทธิภาพโดยการเขียนฟังก์ชั่น "nop" แบบไม่มีอะไรเป็นฟังก์ชันและวิธีการต่าง ๆ นี่คือผลการทั่วไปบางส่วน

>> call_nops
คอมพิวเตอร์: PCWIN เปิดตัว: 2009b
เรียกแต่ละฟังก์ชัน / วิธี 100,000 ครั้ง
ฟังก์ชั่น nop (): 0.02261 วินาที 0.23 usec ต่อการโทรหนึ่งครั้ง
ฟังก์ชั่น nop1-5 (): 0.02182 วินาที 0.22 usec ต่อการโทรหนึ่งครั้ง
ฟังก์ชั่นย่อย nop (): 0.02244 วินาที 0.22 usec ต่อการโทรหนึ่งครั้ง
@ () [] ฟังก์ชั่นไม่ระบุชื่อ: 0.08461 วินาที 0.85 usec ต่อการโทรหนึ่งครั้ง
วิธี nop (obj): 0.24664 วินาที 2.47 usec ต่อการโทร
เมธอด nop1-5 (obj): 0.23469 วินาที 2.35 usec ต่อการโทรหนึ่งครั้ง
nop () ฟังก์ชั่นส่วนตัว: 0.02197 วินาที 0.22 usec ต่อการโทรหนึ่งครั้ง
classdef nop (obj): 0.90547 วินาที 9.05 usec ต่อการโทรหนึ่งครั้ง
classdef obj.nop (): 1.75522 วินาที 17.55 usec ต่อการโทรหนึ่งครั้ง
classdef private_nop (obj): 0.84738 วินาที 8.47 usec ต่อการโทรหนึ่งครั้ง
classdef nop (obj) (m-file): 0.90560 วินาที 9.06 usec ต่อการโทรหนึ่งครั้ง
classdef class.staticnop (): 1.16361 วินาที 11.64 usec ต่อการโทรหนึ่งครั้ง
Java nop (): 2.43035 วินาที 24.30 usec ต่อการโทร
Java static_nop (): 0.87682 วินาที 8.77 usec ต่อการโทรหนึ่งครั้ง
Java nop () จาก Java: 0.00014 วินาที 0.00 usec ต่อการโทร
MEX mexnop (): 0.11409 วินาที 1.14 usec ต่อการโทรหนึ่งครั้ง
C nop (): 0.00001 วินาที 0.00 usec ต่อการโทรหนึ่งครั้ง

ผลลัพธ์ที่คล้ายกันใน R2008a ถึง R2009b นี่คือใน Windows XP x64 ที่ใช้งาน MATLAB แบบ 32 บิต

"Java nop ()" เป็นวิธี Java ที่ไม่ต้องทำอะไรเรียกจากภายในลูป M-code และรวมถึงโอเวอร์เฮดการส่ง MATLAB-to-Java ด้วยการโทรแต่ละครั้ง "Java nop () จาก Java" เป็นสิ่งเดียวกันกับที่เรียกในการวนซ้ำ Java () สำหรับและไม่ต้องเสียค่าปรับขอบเขต ใช้เวลา Java และ C กับเม็ดเกลือ คอมไพเลอร์ฉลาดสามารถเพิ่มประสิทธิภาพการโทรออกไปอย่างสมบูรณ์

กลไกการกำหนดขอบเขตแพ็กเกจเป็นของใหม่เปิดตัวในเวลาเดียวกันกับคลาส classdef พฤติกรรมของมันอาจจะเกี่ยวข้อง

ข้อสรุปเบื้องต้นบางประการ:

  • วิธีการช้ากว่าฟังก์ชั่น
  • ใหม่สไตล์ (classdef) วิธีการช้ากว่าวิธีแบบเก่า
  • obj.nop()ไวยากรณ์ใหม่ช้ากว่าnop(obj)ไวยากรณ์แม้สำหรับวิธีการเดียวกันกับวัตถุ classdef เหมือนกันสำหรับวัตถุ Java (ไม่แสดง) nop(obj)หากคุณต้องการที่จะไปอย่างรวดเร็วโทร
  • เมธอดโอเวอร์เฮดการเรียกใช้สูงกว่า (ประมาณ 2x) ใน MATLAB แบบ 64 บิตบน Windows (ไม่แสดง)
  • การส่งเมธอด MATLAB ช้ากว่าภาษาอื่น

การพูดว่าทำไมจึงเป็นเช่นนั้นเพียงแค่การเก็งกำไรในส่วนของฉัน internals OO ของโปรแกรม MATLAB ไม่ใช่แบบสาธารณะ มันไม่ได้เป็นปัญหาที่แปลแล้วรวบรวมต่อ se - MATLAB มี JIT - แต่การพิมพ์และไวยากรณ์ของ MATLAB อาจทำให้การทำงานมากขึ้นในเวลาทำงาน (เช่นคุณไม่สามารถบอกได้จากไวยากรณ์เพียงอย่างเดียวว่า "f (x)" เป็นการเรียกใช้ฟังก์ชันหรือดัชนีไปยังอาร์เรย์ แต่ขึ้นอยู่กับสถานะของพื้นที่ทำงาน ณ เวลาทำงาน) อาจเป็นเพราะนิยามคลาสของ MATLAB ถูกผูกไว้ ไปยังสถานะระบบไฟล์ในลักษณะที่ภาษาอื่น ๆ ไม่ได้

แล้วจะทำอย่างไรดี?

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

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

จุดคือการจัดเรียงรหัสของคุณเพื่อเล่นจุดแข็งของภาษา - การจัดการอาร์เรย์คณิตศาสตร์เวกเตอร์ - และหลีกเลี่ยงจุดอ่อน

แก้ไข: ตั้งแต่โพสต์ต้นฉบับ R2010b และ R2011a ออกมาแล้ว ภาพรวมเป็นเช่นเดียวกับ MCOs เรียกรับบิตเร็วขึ้นและ Java และวิธีการแบบเก่าโทรได้รับช้า

แก้ไข: ฉันเคยมีบันทึกย่อบางส่วนที่นี่ใน "ความไวเส้นทาง" พร้อมตารางเพิ่มเติมของการกำหนดเวลาการเรียกใช้ฟังก์ชันซึ่งเวลาการทำงานได้รับผลกระทบจากวิธีการกำหนดค่าเส้นทาง Matlab แต่ดูเหมือนจะเป็นความผิดปกติของการตั้งค่าเครือข่ายเฉพาะของฉัน เวลา. แผนภูมิข้างต้นสะท้อนให้เห็นถึงเวลาตามแบบฉบับของความเหนือกว่าของการทดสอบของฉันในช่วงเวลา

อัปเดต: R2011b

แก้ไข (2/13/2012): R2011b ไม่ทำงานและภาพการทำงานมีการเปลี่ยนแปลงมากพอที่จะอัปเดต

Arch: PCWIN เปิดตัว: 2011b 
เครื่อง: R2011b, Windows XP, 8x คอร์ i7-2600 @ 3.40GHz, 3 GB RAM, NVIDIA NVS 300
ทำแต่ละการดำเนินงาน 100,000 ครั้ง
รูปแบบรวม µsec ต่อการโทร
ฟังก์ชัน nop (): 0.01578 0.16
nop (), 10x loop unroll: 0.01477 0.15
nop (), 100x loop unroll: 0.01518 0.15
ฟังก์ชันย่อย nop (): 0.01559 0.16
@ () [] ฟังก์ชั่นไม่ระบุชื่อ: 0.06400 0.64
วิธี nop (obj): 0.28482 2.85
ฟังก์ชั่นส่วนตัว nop (): 0.01505 0.15
classdef nop (obj): 0.43323 4.33
classdef obj.nop (): 0.81087 8.11
classdef private_nop (obj): 0.32272 3.23
classdef class.staticnop (): 0.88959 8.90
classdef คงที่: 1.51890 15.19
คุณสมบัติ classdef: 0.12992 1.30
คุณสมบัติ classdef พร้อมทะลุ: 1.39912 13.99
+ pkg.nop () ฟังก์ชัน: 0.87345 8.73
+ pkg.nop () จากภายใน + pkg: 0.80501 8.05
Java obj.nop (): 1.86378 18.64
Java nop (obj): 0.22645 2.26
Java feval ('nop', obj): 0.52544 5.25
Java Klass.static_nop (): 0.35357 3.54
Java obj.nop () จาก Java: 0.00010 0.00
MEX mexnop (): 0.08709 0.87
C nop (): 0.00001 0.00
j () (builtin): 0.00251 0.03

ฉันคิดว่าผลที่สุดของเรื่องนี้คือ:

  • วิธี MCOS / classdef เร็วขึ้น ราคาใกล้เคียงกับคลาสสไตล์เก่าตราบใดที่คุณใช้foo(obj)ไวยากรณ์ ดังนั้นความเร็วของเมธอดจึงไม่ใช่เหตุผลที่จะใช้คลาสคลาสสิกในกรณีส่วนใหญ่อีกต่อไป (คำชื่นชม, MathWorks!)
  • วางฟังก์ชั่นใน namespaces ทำให้พวกเขาช้า (ไม่ใช่ใหม่ใน R2011b เพียงใหม่ในการทดสอบของฉัน)

อัปเดต: R2014a

ฉันสร้างรหัสการเปรียบเทียบและเรียกใช้บน R2014a ใหม่

Matlab R2014a บน PCWIN64  
Matlab 8.3.0.532 (R2014a) / Java 1.7.0_11 บน PCWIN64 Windows 7 6.1 (eilonwy-win7) 
เครื่อง: Core i7-3615QM CPU @ 2.30GHz, RAM 4 GB (แพลตฟอร์ม VMware เสมือน)
nIters = 100000 

เวลาทำการ (µsec)  
ฟังก์ชั่น nop (): 0.14 
ฟังก์ชั่นย่อย nop (): 0.14 
@ () [] ฟังก์ชั่นไม่ระบุชื่อ: 0.69 
วิธี nop (obj): 3.28 
nop () ไพรเวต fcn บน @class: 0.14 
classdef nop (obj): 5.30 
classdef obj.nop (): 10.78 
classdef pivate_nop (obj): 4.88 
classdef class.static_nop (): 11.81 
classdef คงที่: 4.18 
คุณสมบัติ classdef: 1.18 
คุณสมบัติ classdef พร้อม getter: 19.26 
+ pkg.nop () ฟังก์ชั่น: 4.03 
+ pkg.nop () จากด้านใน + pkg: 4.16 
feval ('nop'): 2.31 
feval (@nop): 0.22 
eval ('nop'): 59.46 
Java obj.nop (): 26.07 
Java nop (obj): 3.72 
Java feval ('nop', obj): 9.25 
Java Klass.staticNop (): 10.54 
Java obj.nop () จาก Java: 0.01 
MEX mexnop (): 0.91 
builtin j (): 0.02 
การเข้าถึงฟิลด์ struct s.foo: 0.14 
isempty (ถาวร): 0.00 

อัพเดท: R2015b: วัตถุเร็วขึ้น!

นี่คือผลลัพธ์ R2015b ของโปรดได้รับจาก @Shaked นี่เป็นการเปลี่ยนแปลงครั้งใหญ่ : OOP เร็วขึ้นอย่างมากและขณะนี้obj.method()ไวยากรณ์เร็วเท่าmethod(obj)และเร็วกว่าวัตถุ OOP รุ่นเก่า

Matlab R2015b บน PCWIN64  
Matlab 8.6.0.267246 (R2015b) / Java 1.7.0_60 บน PCWIN64 Windows 8 6.2 (nanit-shaked) 
เครื่อง: Core i7-4720HQ CPU @ 2.60GHz, RAM 16 GB (20378)
nIters = 100000 

เวลาทำการ (µsec)  
ฟังก์ชั่น nop (): 0.04 
ฟังก์ชันย่อย nop (): 0.08 
@ () [] ฟังก์ชั่นไม่ระบุชื่อ: 1.83 
วิธี nop (obj): 3.15 
nop () ไพรเวต fcn บน @class: 0.04 
classdef nop (obj): 0.28 
classdef obj.nop (): 0.31 
classdef pivate_nop (obj): 0.34 
classdef class.static_nop (): 0.05 
classdef คงที่: 0.25 
คุณสมบัติ classdef: 0.25 
คุณสมบัติ classdef พร้อม getter: 0.64 
+ pkg.nop () ฟังก์ชัน: 0.04 
+ pkg.nop () จากภายใน + pkg: 0.04 
feval ('nop'): 8.26 
feval (@nop): 0.63 
eval ('nop'): 21.22 
Java obj.nop (): 14.15 
Java nop (obj): 2.50 
Java feval ('nop', obj): 10.30 
Java Klass.staticNop (): 24.48 
Java obj.nop () จาก Java: 0.01 
MEX mexnop (): 0.33 
builtin j (): 0.15 
struct s.foo การเข้าถึงข้อมูล: 0.25 
isempty (ถาวร): 0.13 

อัปเดต: R2018a

นี่คือผลลัพธ์ของ R2018a มันไม่ใช่การกระโดดครั้งใหญ่ที่เราเห็นเมื่อมีการเปิดตัวเอ็นจิ้นการประมวลผลใหม่ใน R2015b แต่ก็ยังคงเป็นปีที่ดีกว่าปีที่ผ่านมา สะดุดตาฟังก์ชั่นที่ไม่ระบุชื่อได้เร็วขึ้นทาง

Matlab R2018a บน MACI64  
Matlab 9.4.0.813654 (R2018a) / Java 1.8.0_144 บน MACI64 Mac OS X 10.13.5 (eilonwy) 
เครื่อง: Core i7-3615QM CPU @ 2.30GHz, RAM 16 GB 
nIters = 100000 

เวลาทำการ (µsec)  
ฟังก์ชั่น nop (): 0.03 
ฟังก์ชันย่อย nop (): 0.04 
@ () [] ฟังก์ชั่นไม่ระบุชื่อ: 0.16 
classdef nop (obj): 0.16 
classdef obj.nop (): 0.17 
classdef pivate_nop (obj): 0.16 
classdef class.static_nop (): 0.03 
classdef คงที่: 0.16 
คุณสมบัติ classdef: 0.13 
คุณสมบัติ classdef พร้อม getter: 0.39 
+ pkg.nop () ฟังก์ชัน: 0.02 
+ pkg.nop () จากด้านใน + pkg: 0.02 
feval ('nop'): 15.62 
feval (@nop): 0.43 
eval ('nop'): 32.08 
Java obj.nop (): 28.77 
Java nop (obj): 8.02 
Java feval ('nop', obj): 21.85 
Java Klass.staticNop (): 45.49 
Java obj.nop () จาก Java: 0.03 
MEX mexnop (): 3.54 
builtin j (): 0.10 
struct s.foo การเข้าถึงข้อมูล: 0.16 
isempty (ถาวร): 0.07 

อัปเดต: R2018b และ R2019a: ไม่มีการเปลี่ยนแปลง

ไม่มีการเปลี่ยนแปลงที่สำคัญ ฉันไม่ได้กังวลที่จะรวมผลการทดสอบ

รหัสที่มาสำหรับการวัดประสิทธิภาพ

ฉันได้วางซอร์สโค้ดสำหรับการวัดประสิทธิภาพเหล่านี้บน GitHub ซึ่งเผยแพร่ภายใต้ใบอนุญาต MIT https://github.com/apjanke/matlab-bench


5
@AndrewJanke คุณคิดว่าคุณสามารถรันมาตรฐานอีกครั้งด้วย R2012a ได้หรือไม่? มันน่าสนใจจริงๆ
Dang Khoa

7
สวัสดีชาวบ้าน หากคุณยังคงสนใจซอร์สโค้ดฉันได้สร้างมันขึ้นมาใหม่และเปิดซอร์สบน GitHub github.com/apjanke/matlab-bench
Andrew Janke

2
@Seeda: วิธีการแบบคงที่จะแสดงรายการเป็น "classdef class.static_nop ()" ในผลลัพธ์เหล่านี้ ค่อนข้างช้าเมื่อเทียบกับฟังก์ชั่น หากพวกเขาไม่ได้ถูกเรียกบ่อยนั่นก็ไม่สำคัญ
Andrew Janke

2
@AndrewJanke นี่คือ: gist.github.com/ShakedDovrat/62db9e8f6883c5e28fc0
Shaked

2
ว้าว! หากผลลัพธ์เหล่านั้นหยุดชะงักฉันอาจต้องแก้ไขคำตอบทั้งหมดนี้ ที่เพิ่ม ขอบคุณ!
Andrew Janke

3

ระดับการจัดการมีค่าใช้จ่ายเพิ่มเติมจากการติดตามการอ้างอิงทั้งหมดไปยังตัวเองเพื่อวัตถุประสงค์ในการล้างข้อมูล

ลองการทดสอบเดียวกันโดยไม่ใช้คลาสการจัดการและดูผลลัพธ์ของคุณ


1
การทดสอบเดียวกันกับ String แต่ตอนนี้เป็น class value (บนเครื่องอื่น) atest: 0.009, btest: o.356 นั่นคือความแตกต่างเช่นเดียวกับที่จับดังนั้นฉันไม่คิดว่าการอ้างอิงการติดตามเป็นคำตอบที่สำคัญ มันไม่ได้อธิบายค่าใช้จ่ายในฟังก์ชั่นกับฟังก์ชั่นในแพคเกจ
stijn

คุณใช้ MATLAB รุ่นใดอยู่
MikeEL

1
ฉันใช้การเปรียบเทียบที่คล้ายกันระหว่างคลาสตัวจัดการและคลาสค่าและไม่ได้สังเกตเห็นความแตกต่างของประสิทธิภาพระหว่างทั้งสอง
RjOllos

ฉันไม่สังเกตเห็นความแตกต่างอีกต่อไป
MikeEL

เหมาะสม: ใน Matlab อาร์เรย์ทั้งหมดไม่ใช่แค่จัดการกับวัตถุเท่านั้นที่จะถูกอ้างอิงเพราะพวกมันใช้ copy-on-write และแชร์ข้อมูลดิบพื้นฐาน
Andrew Janke

1

ประสิทธิภาพของ OO ขึ้นอยู่กับรุ่นของ MATLAB ที่ใช้ ฉันไม่สามารถแสดงความคิดเห็นกับทุกรุ่น แต่รู้จากประสบการณ์ว่า 2012a นั้นได้รับการปรับปรุงให้ดีกว่าเวอร์ชัน 2010 มาก ไม่มีมาตรฐานและไม่มีตัวเลขแสดง รหัสของฉันเขียนเฉพาะโดยใช้คลาสการจัดการและเขียนภายใต้ 2012a จะไม่ทำงานเลยในเวอร์ชันก่อนหน้า


1

จริงๆแล้วไม่มีปัญหากับรหัสของคุณ แต่มันเป็นปัญหากับ Matlab ฉันคิดว่ามันเป็นการเล่นที่ทำให้ดูเหมือน มันไม่มีอะไรนอกจากค่าใช้จ่ายในการรวบรวมรหัสชั้นเรียน ฉันได้ทำการทดสอบโดยใช้คลาสแบบง่าย (หนึ่งครั้งเป็นที่จับ) และอีกอัน (หนึ่งครั้งเป็นคลาสที่มีค่า)

    classdef Pointh < handle
    properties
       X
       Y
    end  
    methods        
        function p = Pointh (x,y)
            p.X = x;
            p.Y = y;
        end        
        function  d = dist(p,p1)
            d = (p.X - p1.X)^2 + (p.Y - p1.Y)^2 ;
        end

    end
end

นี่คือการทดสอบ

%handle points 
ph = Pointh(1,2);
ph1 = Pointh(2,3);

%values  points 
p = Pointh(1,2);
p1 = Pointh(2,3);

% vector points
pa1 = [1 2 ];
pa2 = [2 3 ];

%Structur points 
Ps.X = 1;
Ps.Y = 2;
ps1.X = 2;
ps1.Y = 3;

N = 1000000;

tic
for i =1:N
    ph.dist(ph1);
end
t1 = toc

tic
for i =1:N
    p.dist(p1);
end
t2 = toc

tic
for i =1:N
    norm(pa1-pa2)^2;
end
t3 = toc

tic
for i =1:N
    (Ps.X-ps1.X)^2+(Ps.Y-ps1.Y)^2;
end
t4 = toc

ผลลัพธ์ t1 =

จัดการ 12.0212%

t2 =

ค่า 12.0042%

t3 =

0.5489  % vector

t4 =

0.0707 % structure 

ดังนั้นเพื่อประสิทธิภาพที่มีประสิทธิภาพหลีกเลี่ยงการใช้ OOP แทนโครงสร้างเป็นตัวเลือกที่ดีในการจัดกลุ่มตัวแปร

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