J'ai travaillé avec OO MATLAB pour un moment, et finit par regarder similaires problèmes de performances.
La réponse courte est: oui, MATLAB programmation orientée objet est une sorte de lente. Il est important appel de la méthode des frais généraux, plus élevé que l'ensemble des langages à objets, et il n'y a pas beaucoup que vous pouvez faire à ce sujet. Partie de la raison peut être que idiomatiques MATLAB utilise "vectorisé" code afin de réduire le nombre d'appels de méthode, et par appel de frais généraux n'est pas une priorité.
J'ai comparé les performances en écriture ne rien faire "nop" fonctionne comme les différents types de fonctions et de méthodes. Voici quelques résultats typiques.
>> call_nops
Ordinateur: PCWIN de presse: 2009b
Dans un appel de fonction/méthode 100000 fois
nop() fonction: 0.02261 sec 0.23 usec par appel
nop1-5() fonctions: 0.02182 s 0,22 usec par appel
nop() sous-fonction: 0.02244 s 0,22 usec par appel
@()[] fonction anonyme: 0.08461 sec 0.85 usec par appel
nop(obj) méthode: 0.24664 sec 2.47 usec par appel
nop1-5(obj) méthodes: 0.23469 sec 2.35 usec par appel
nop() fonction privée: 0.02197 s 0,22 usec par appel
classdef nop(obj): 0.90547 sec 9.05 usec par appel
classdef obj.nop(): 1.75522 sec 17.55 usec par appel
classdef private_nop(obj): 0.84738 sec 8.47 usec par appel
classdef nop(obj) (m-file): 0.90560 sec 9.06 usec par appel
classdef classe.staticnop(): 1.16361 sec 11.64 usec par appel
Java nop(): 2.43035 sec 24.30 usec par appel
Java static_nop(): 0.87682 sec 8.77 usec par appel
Java nop() de Java: 0.00014 sec 0.00 usec par appel
MEX mexnop(): 0.11409 sec 1.14 usec par appel
C nop(): 0.00001 sec 0.00 usec par appel
Des résultats similaires sur R2008a par R2009b. C'est sur Windows XP x64 cours d'exécution 32 bits MATLAB.
Le "Java nop()" est un méthode en Java appelée à partir de l'intérieur d'un M-code de la boucle, et comprend l'MATLAB-à-Java de répartition des frais généraux grâce à chaque appel. "Java nop() de Java" est la même chose appelé dans une Java boucle for() et ne pas occasionner de cette limite de pénalité. Prendre le Java et le C timings avec un grain de sel; un habile compilateur peut optimiser les appels par disparaître complètement.
Le paquet de portée mécanisme est nouveau, introduit à la même époque que le classdef classes. Son comportement peut être lié.
Quelques conclusions provisoires:
- Les méthodes sont plus lents que les fonctions.
- Nouveau style (classdef) les méthodes sont plus lents que les vieux style de méthodes.
- Le nouveau
obj.nop()
syntaxe est plus lent que l' nop(obj)
de la syntaxe, même pour la même méthode sur un classdef objet. De même pour les objets Java (non illustré). Si vous voulez aller vite, appelez - nop(obj)
.
- Appel de la méthode de surcharge est plus élevée (environ 2x) en 64 bits MATLAB sous Windows. (Non présenté).
- MATLAB répartition de méthode est plus lente que celle d'autres langues.
Le fait de dire pourquoi il en est ainsi serait juste de la spéculation de ma part. Le MATLAB du moteur OO internes ne sont pas publics. Il n'est pas interprété vs question compilé en soi - MATLAB dispose d'une équipe commune d'enquête - mais MATLAB looser de frappe et de syntaxe peut signifier plus de travail au moment de l'exécution. (E. g. vous ne pouvez pas dire à partir de la syntaxe ou du moins si, f(x)" est un appel de fonction ou d'un indice dans un tableau; elle dépend de l'état de l'espace de travail au moment de l'exécution.) Il est peut-être parce que MATLAB définitions de classe sont liés à système de fichiers de l'état en sorte que de nombreuses autres langues " ne le sont pas.
Alors, que faire?
Un idiomatiques MATLAB approche pour ce qui est de "vectoriser" votre code par la structuration de vos définitions de classe telle qu'une instance d'objet encapsule un tableau; c'est à chacun de ses champs de tenir des tableaux parallèles (appelé "planes" de l'organisation dans la documentation MATLAB). Plutôt que d'avoir un tableau d'objets, chacun avec des champs de portefeuille de valeurs scalaires, de définir des objets qui sont eux-mêmes des tableaux, et ont les méthodes prennent des tableaux d'entrées, et de faire vectorisé appels sur les champs et les entrées. Cela réduit le nombre d'appels de méthode faite, je l'espère assez que l'expédition de frais généraux n'est pas un goulot d'étranglement.
Imitant un C++ ou Java de la classe dans MATLAB ne sera probablement pas optimale. Java/C++ classes sont généralement construits tels que les objets sont les plus petits blocs de construction, aussi précis que vous le pouvez (qui est, beaucoup de classes différentes), et vous les composent dans des tableaux, objets de collection, etc, et itérer sur eux avec des boucles. Pour faire rapide MATLAB classes, tour qui approche à l'intérieur. Les classes sont plus grandes dont les champs sont des tableaux, et d'appeler vectorisé méthodes sur ces tableaux.
Le point est d'organiser votre code pour jouer sur les points forts de la langue - tableau de manutention, vectorisé mathématiques et d'éviter les points faibles.
EDIT: Depuis le post original, R2010b et R2011a viennent. L'ensemble de l'image est la même, avec le MCO des appels d'obtenir un peu plus vite, et Java et de style ancien appels de méthode arriver plus lent.
EDIT: j'ai utilisé quelques notes, ici, sur le "chemin de la sensibilité" avec une table supplémentaire d'appel de fonction timings, où les durées de fonctionnement ont été touchés par la façon dont le Matlab chemin a été configuré, mais qui semble avoir été une aberration de ma configuration réseau particulière à l'époque. Le graphique ci-dessus reflète la fois typique de la prépondérance de mes tests au fil du temps.
Mise À Jour: R2011b
EDIT (2/13/2012): R2011b et, à l'image de performances a suffisamment changé pour mettre à jour ce.
Arc: PCWIN de presse: 2011b
Machine: R2011b, Windows XP, 8x Core i7-2600 @ 3.40 GHz, 3 GO de RAM, NVIDIA NVS 300
Chaque opération de 100000 fois
le style total µs par appel
nop() fonction: 0.16 0.01578
nop(), 10x déroulement des boucles: 0.15 0.01477
nop(), 100x déroulement des boucles: 0.15 0.01518
nop() sous-fonction: 0.16 0.01559
@()[] fonction anonyme: 0.64 0.06400
nop(obj) méthode: 0.28482 2.85
nop() fonction privée: 0.15 0.01505
classdef nop(obj): 4.33 0.43323
classdef obj.nop(): 0.81087 8.11
classdef private_nop(obj): 0.32272 3.23
classdef classe.staticnop(): 0.88959 de 8,90
classdef constante: 1.51890 15.19
classdef propriété: 0.12992 1.30
classdef propriété avec getter: 1.39912 13.99
+pkg.nop() fonction: 0.87345 8.73
+pkg.nop() à l'intérieur +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 de 5,25
Java Klass.static_nop(): 0.35357 3.54
Java obj.nop() de Java: 0.00010 0.00
MEX mexnop(): 0.08709 0.87
C nop(): 0.00001 0.00
j() (builtin): 0.03 0.00251
Je pense que le résultat de ceci est que:
- MCO/classdef méthodes sont plus rapides. Le coût est maintenant à égalité avec les anciennes classes de style, aussi longtemps que vous utilisez l'
foo(obj)
de la syntaxe. Donc, la méthode de la vitesse n'est plus une raison de rester avec les anciennes classes de style dans la plupart des cas. (Bravo, MathWorks!)
- Mettre des fonctions dans les espaces de noms les rend lent. (Pas nouvelle dans R2011b, tout nouveau dans mon test).
Mise À Jour: R2014a
J'ai reconstruit l'analyse comparative de code et l'exécuter sur R2014a.
Matlab R2014a sur PCWIN64
Matlab 8.3.0.532 (R2014a) / Java 1.7.0_11 sur PCWIN64 Windows 7 6.1 (eilonwy-win7)
Machine: Core i7-3615QM CPU @ 2.30 GHz, 4 GO de RAM (VMware Plate-forme Virtuelle)
nIters = 100000
Temps de fonctionnement (µs)
nop() fonction: 0.14
nop() sous-fonction: 0.14
@()[] fonction anonyme: 0.69
nop(obj) méthode: 3.28
nop() privé fcn sur @class: 0.14
classdef nop(obj): 5.30
classdef obj.nop(): 10.78
classdef pivate_nop(obj): 4.88
classdef classe.static_nop(): 11.81
classdef constante: 4.18
classdef propriété: 1.18
classdef propriété avec getter: 19.26
+pkg.nop() fonction: 4.03
+pkg.nop() à l'intérieur +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() de Java: 0.01
MEX mexnop(): 0.91
builtin j(): 0.02
struct s.foo domaine de l'accès: 0.14
isempty(persistant): 0.00
Le Code Source de Repères
J'ai mis le code source de ces critères sur GitHub, publié sous la Licence MIT. https://github.com/apjanke/matlab-bench