SORU
7 Kasım 2009, CUMARTESİ


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
16 Kasım 2009, PAZARTESİ


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özdizimi nop(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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Matthew Smith

    Matthew Smit

    24 Mayıs 2010
  • Santozz Yazz

    Santozz Yazz

    23 Mart 2014
  • Thom Hall

    Thom Hall

    24 Kasım 2006