MATLAB OOP yavaş ya da yanlış bir şey mi yapıyorum?
Ben deneme yanılma ile MATLAB OOP, bir başlangıç olarak ben taklit benim C 'nin Logger sınıflar ve atıyorum benim dize yardımcı fonksiyonları bir String sınıfı, düşünce harika olur yapar gibi şeyler a b
, a == b
, a.find( b )
yerine
strcat( a b )
, strcmp( a, b )
, al strfind( a, b )
, vb ilk element.
Sorun: yavaşlama
Yukarıdaki şeyleri kullanmak için koydum ve hemen fark ettimsertyavaşlama. Yanlış tercih MATLAB deneyim sınırlıdır olarak kesinlikle mümkün olan) yapıyor, ya da C = OOP sadece çok yük getirmektedir mıyım?
Testimi
İşte dize için yaptığım basit test, temelde sadece bir dize ekleme ve yeniden eklenen kısmı kaldırarak:
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' );
Sonuçları
Saniye cinsinden toplam süre, 1000 yineleme:
btest 0.550 (String.0.138, Dize SetLength.artı 0.065, Dize.Uzunluk) 0.057
en iyi ihtimalle 0.015
Logger sistemi için sonuç aynı: 1000 aramalar için 0.1 saniye
frpintf( 1, 'test\n' )
, 7 (!) saniye için 1000 aramaları için benim sistemi kullanırken Dize sınıfı, dahili (TAMAM, çok fazla mantık, ama karşılaştırmak için C : yükü benim sistem kullanan std::string( "blah" )
std::cout
çıkış tarafı vs normal std::cout << "blah"
sipariş 1 milisaniye.)
Sınıf/paket fonksiyonları ararken sadece havai mı?
MATLAB yorumlanır bu yana, zamanında fonksiyon/nesne tanımına bakalım. Belki çok daha fazla yük yolunda sınıf veya paket fonksiyonu vs fonksiyonları ararken dahil olduğunu merak ettim. Bu test için denedim, ve sadece yabancı alır. Sınıfları/nesneleri etkisini ekarte etmek için, yol vs bir işlev çağırarak bir paket içinde bir işlev karşılaştırdım:
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
Sonuçlar, aynı şekilde yukarıdaki gibi toplanmış:
sn, hassasiyeti 0,001 sn ctest içinde 0.004 en iyi ihtimalle
sn, 0.014 saniye içinde açıklama 0.060 btest.ctest
Bütün bu yükü, bu yükü doğrudan yolu fonksiyonları için değildir Oysa bu OOP uygulama için MATLAB vakit tanımları ararken gelen?
CEVAP
Bir süre OO deposunda bulunan çalışıyordum ve benzer performans sorunları bakarak sona erdi.
Kısa cevap: evet, C = OOP biraz yavaş. Önemli yöntem Tepegöz, ana dilleri OO daha yüksek bir çağrı var, ve bu konuda yapabileceğin fazla bir şey yok. Bölüm neden bu deyimsel MATLAB kullanır "" yöntem çağrılarının sayısını azaltmak için bir kod ve her çağrı yükü yüksek bir öncelik değil. vektörize olabilir
Yazma performansı-hiçbir şey yapmadan "" işlevleri ve yöntemleri çeşitli türleri olarak işlev görür. nop ben, karşılaştırılan İşte bazı tipik sonuçlar.
>> call_nops Computer: PCWIN Release: 2009b Calling each function/method 100000 times nop() function: 0.02261 sec 0.23 usec per call nop1-5() functions: 0.02182 sec 0.22 usec per call nop() subfunction: 0.02244 sec 0.22 usec per call @()[] anonymous function: 0.08461 sec 0.85 usec per call nop(obj) method: 0.24664 sec 2.47 usec per call nop1-5(obj) methods: 0.23469 sec 2.35 usec per call nop() private function: 0.02197 sec 0.22 usec per call classdef nop(obj): 0.90547 sec 9.05 usec per call classdef obj.nop(): 1.75522 sec 17.55 usec per call classdef private_nop(obj): 0.84738 sec 8.47 usec per call classdef nop(obj) (m-file): 0.90560 sec 9.06 usec per call classdef class.staticnop(): 1.16361 sec 11.64 usec per call Java nop(): 2.43035 sec 24.30 usec per call Java static_nop(): 0.87682 sec 8.77 usec per call Java nop() from Java: 0.00014 sec 0.00 usec per call MEX mexnop(): 0.11409 sec 1.14 usec per call C nop(): 0.00001 sec 0.00 usec per call
R2009b ile R2008a benzer sonuçlar. Bu Windows XP x 64 32-bit MATLAB çalışıyor.
"Java nop ()"-hiçbir şey Java yöntemi M-kodu bir döngü içinde aramış ile MATLAB-Java sevk yükü içerir. "Java nop() Java" aynı şey için bir Java denir() döngü ve bu sınır cezaya tabi değil. İnanmayarak Java ve C zamanlamaları al; akıllı bir derleyici çağrıları tamamen optimize olabilir.
Paket kapsamı mekanizması yeni, classdef sınıfları aynı anda tanıtıldı. Onun davranışı ile ilgili olabilir.
Birkaç geçici sonuçlar:
- Yöntemleri fonksiyonları daha yavaş.
- Yeni stil (classdef) yöntemleri eski tarz yöntemlere göre daha yavaştır.
obj.nop()
yeni sözdiziminop(obj)
sözdizimi daha yavaş, hatta classdef bir nesne üzerinde aynı yöntem. Java nesneleri (gösterilmez) için aynı. Eğer hızlı gitmek istiyorsan,nop(obj)
Ara.- Yöntem çağrısı yükü yüksek (yaklaşık 2x) 64-bit Windows üzerinde MATLAB. (Gösterilir.)
- MATLAB yöntem, bazı diğer dillere göre daha yavaştır gönderme.
Bunun neden böyle olduğunu söyleyerek sadece benim parçası üzerinde spekülasyon olur. MATLAB motorun OO iç halka açık değil. Yorumlanan vs derlenmiş bir sorun değildir - hesapların yapılabilmesi JİT - ama C = gevşek yazım ve sözdizimi zamanında daha fazla iş anlamına gelebilir. (E. g. "f(x)" fonksiyonu bir çağrı veya bir diziye bir dizin; çalışma zamanında çalışma durumuna bağlıdır.) olup olmadığını sözdizimi yalnız söyleyemezsin C = sınıf tanımları bir şekilde dosya devlete bağlı birçok diğer diller' değildir. çünkü olabilir
Şimdi ne olacak?
Bir deyimsel MATLAB yaklaşım bu olduğu için "vektörize" kodu ile yapılanma sınıf tanımları böyle bir nesne örneği sarar bir dizi; yani, her birinin kendi alanları tutun paralel diziler ("planar" organizasyonunda MATLAB belgeleri). Yerine sahip bir nesneler dizisi, her ile alanları tutan skaler değerleri, nesneleri tanımlamak hangi diziler kendilerini ve yöntemlerini kabul diziler olarak girdi ve vectorized arama alanları ve girdiler. Bu yöntem çağrıları, sevk yükü olan bir darboğaz olmadığını umarım yeterince yapılmış sayısını azaltır.
MATLAB C ya da Java sınıfı taklit muhtemelen uygun olmayacaktır. Java/C sınıfları genellikle inşa edilen bu nesneler en küçük yapı taşı olarak özel olarak (yani, bir sürü farklı sınıflar), ve oluşturmak için onları diziler, koleksiyon nesneleri, vb, ve üzerinde yineleme onlarla döngüler. Hızlı MATLAB dersleri yapmak için, bu yaklaşım ters çevirin. Diziler ve bu diziler hakkında vectorized yöntemleri çağırmak kimin daha büyük sınıflar var.
Nokta kodunuzu dil - dizi işleme, vectorized matematik - güçlerini kullan ve zayıf noktaları önlemek için organize etmektir.
Orijinal yazı, R2010b ve R2011a gel Beri. EDİT: Genel resim aynı, MCOS aramaları biraz daha hızlı, ve Java ve tarzı eski yöntem çağrıları alıyorumyavaş.
EDİT: eskiden bazı notlar burada "path hassasiyeti" ile ek bir tablo işlev çağrısı zamanlama, nereye işlevi zamanlardı etkilenen nasıl Matlab yol yapılandırılmış, ama görünüşünden anlaşıldığı kadarıyla bir sapma belirli bir ağ Kur. Yukarıdaki grafik, bu kez zamanla testlerim üstünlüğü tipik yansıtır.
Güncelleme: R2011b
DÜZENLE (2/13/2012): R2011b ve performans resim bu güncelleme için yeterince değişti.
Arch: PCWIN Release: 2011b Machine: R2011b, Windows XP, 8x Core i7-2600 @ 3.40GHz, 3 GB RAM, NVIDIA NVS 300 Doing each operation 100000 times style total µsec per call nop() function: 0.01578 0.16 nop(), 10x loop unroll: 0.01477 0.15 nop(), 100x loop unroll: 0.01518 0.15 nop() subfunction: 0.01559 0.16 @()[] anonymous function: 0.06400 0.64 nop(obj) method: 0.28482 2.85 nop() private function: 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 constant: 1.51890 15.19 classdef property: 0.12992 1.30 classdef property with getter: 1.39912 13.99 pkg.nop() function: 0.87345 8.73 pkg.nop() from inside 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() from Java: 0.00010 0.00 MEX mexnop(): 0.08709 0.87 C nop(): 0.00001 0.00 j() (builtin): 0.00251 0.03
Bu sonuç bu bence
- MCOS/classdef yöntemlerden daha hızlıdır. Maliyeti şimdi eski stil sınıfları,
foo(obj)
sözdizimi kullandığınız sürece ile eşit. Yöntem hızı artık pek çok durumda, eski tip sınıflar ile sopa için bir sebeptir. (Şeref, MathWorks!) - Ad işlevleri koyarak onları yavaş yapar. (Yeni R2011b, ben sadece yeni bir test.)
Güncelleme: R2014a
Kıyaslama kodunu yeniden inşa ve R2014a üzerine aday oldum.
Matlab R2014a on PCWIN64 Matlab 8.3.0.532 (R2014a) / Java 1.7.0_11 on PCWIN64 Windows 7 6.1 (eilonwy-win7) Machine: Core i7-3615QM CPU @ 2.30GHz, 4 GB RAM (VMware Virtual Platform) nIters = 100000 Operation Time (µsec) nop() function: 0.14 nop() subfunction: 0.14 @()[] anonymous function: 0.69 nop(obj) method: 3.28 nop() private fcn on @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 constant: 4.18 classdef property: 1.18 classdef property with getter: 19.26 pkg.nop() function: 4.03 pkg.nop() from inside 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() from Java: 0.01 MEX mexnop(): 0.91 builtin j(): 0.02 struct s.foo field access: 0.14 isempty(persistent): 0.00
Güncelleme: R2015b : Nesneleri daha hızlı!
Burada R2015b sonuçları, nazikçe @Çalkalanır tarafından sağlanan. Bu birbüyükdeğiştir: OOP oldukça hızlıdır, ve şimdi obj.method()
sözdizimi çok daha hızlı method(obj)
daha.
Matlab R2015b on PCWIN64 Matlab 8.6.0.267246 (R2015b) / Java 1.7.0_60 on PCWIN64 Windows 8 6.2 (nanit-shaked) Machine: Core i7-4720HQ CPU @ 2.60GHz, 16 GB RAM (20378) nIters = 100000 Operation Time (µsec) nop() function: 0.04 nop() subfunction: 0.08 @()[] anonymous function: 1.83 nop(obj) method: 3.15 nop() private fcn on @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 constant: 0.25 classdef property: 0.25 classdef property with getter: 0.64 pkg.nop() function: 0.04 pkg.nop() from inside 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() from Java: 0.01 MEX mexnop(): 0.33 builtin j(): 0.15 struct s.foo field access: 0.25 isempty(persistent): 0.13
Kaynak Kriterler için Kod
Bu kriterler GitHub, MIT Lisansı altında kaynak kodu koydum. https://github.com/apjanke/matlab-bench
arrayfun matlab açık bir döngü daha ön...
Görünümü denetleyicisi'görünüm - ...
(Razor) MVC 3 Ajax ASP.NET .ActionLink...
Yepyeni' yeni FİKİR 13 yavaş arac...
sistemi("pause"); - Neden ya...