Impact of OREF support
There are some classes in our code base that contain Methods only (no properties). I told my colleagues that converting them into the ClassMethods should improve performance as it would eliminate unnecessary OREF support at run-time. Some of them replied that it would be microseconds, so what is the reason to bother.
Is it possible to estimate the impact of OREF support of method calls at run-time? E.g., as a % of all CPU load.
Comments
Will they ever be overridden or are you just calling them Class.Method
To put pure methods in abstract or not purely depends if it can be overridden.
I have never been sure what ProcedureBlock 0 or 1 means in terms of internal procedures. Can you pls put some light on it?
Wondeful
Thanks!
One headache less in the discussion about the "right" way to write code.
+a tiny piece for "creative freedom".
![]()
Changed a bit and added new code:
<FONT COLOR="#000080">/// d ##class(Scratch.test).ClassVsInst()
ClassMethod </FONT><FONT COLOR="#000000">ClassVsInst(</FONT><FONT COLOR="#ff00ff">N </FONT><FONT COLOR="#000000">= {1e6}) [ </FONT><FONT COLOR="#000080">ProcedureBlock </FONT><FONT COLOR="#000000">= 0, </FONT><FONT COLOR="#000080">PublicList </FONT><FONT COLOR="#000000">= st ]
{
</FONT><FONT COLOR="#0000ff">n </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">xClass</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">xInst</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">st
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"пропоывшыщзшвыщшв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"гшщыгвыовлдыовдьыовдлоыдлв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"widuiowudoiwudoiwudoiwud"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"прпроыпворыпворыпворыпв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"uywyiusywisywzxbabzjhagjЭ"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"пропоывшыщзшвыщшв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"гшщыгвыовлдыовдьыовдлоыдлв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"widuiowudoiwudoiwudoiwud"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"прпроыпворыпворыпворыпв"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"uywyiusywisywzxbabzjhagjЭ"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xClass</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"(args...) f i=1:1:N s sc=##class(Scratch.test).%1(args...)"
</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xInst</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"(args...) f i=1:1:N s sc=st.%1(args...)"
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">Scratch.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">()
</FONT><FONT COLOR="#0000ff">w $p</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$zv</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"(Build"</FONT><FONT COLOR="#000000">),!!
</FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#ff0000">runClassmethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass10"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass10"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInst10"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runClassmethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass5"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass5"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInst5"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runClassmethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClassNull"</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClassNull"</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInstNull"</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass10"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xClass</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInst10"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xInst</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p6</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p7</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p8</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p9</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p10</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClass5"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xClass</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInst5"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xInst</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p1</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p2</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p3</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p4</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">p5</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyClassNull"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xClass</FONT><FONT COLOR="#000000">)
,</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dummyInstNull"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">xInst</FONT><FONT COLOR="#000000">)
</FONT><FONT COLOR="#ff0000">runMethod</FONT><FONT COLOR="#000000">(methodname,args...)
</FONT><FONT COLOR="#0000ff">n </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">sc
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">N </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sc</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$method</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">args</FONT><FONT COLOR="#000000">...)
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">t </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000">,?16,</FONT><FONT COLOR="#008000">"total time = "</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,?38,</FONT><FONT COLOR="#008000">"avg time = "</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">/</FONT><FONT COLOR="#800000">N</FONT><FONT COLOR="#000000">),!
</FONT><FONT COLOR="#0000ff">q
</FONT><FONT COLOR="#ff0000">runClassmethod</FONT><FONT COLOR="#000000">(methodname,args...)
</FONT><FONT COLOR="#0000ff">n </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">sc
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">N </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sc</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$classmethod</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"Scratch.test"</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#800000">args</FONT><FONT COLOR="#000000">...)
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">t </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#008000">"*"</FONT><FONT COLOR="#000000">,?16,</FONT><FONT COLOR="#008000">"total time = "</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,?38,</FONT><FONT COLOR="#008000">"avg time = "</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">/</FONT><FONT COLOR="#800000">N</FONT><FONT COLOR="#000000">),!
</FONT><FONT COLOR="#0000ff">q
</FONT><FONT COLOR="#ff0000">runX</FONT><FONT COLOR="#000000">(methodname,x,args...)
</FONT><FONT COLOR="#0000ff">n </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">sc
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh
x </FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$$$FormatText</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">x</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000">), </FONT><FONT COLOR="#800000">args</FONT><FONT COLOR="#000000">...)
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zh</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">t </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#008000">"X"</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">methodname</FONT><FONT COLOR="#000000">,?16,</FONT><FONT COLOR="#008000">"total time = "</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">,?38,</FONT><FONT COLOR="#008000">"avg time = "</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">t</FONT><FONT COLOR="#000000">/</FONT><FONT COLOR="#800000">N</FONT><FONT COLOR="#000000">),!
</FONT><FONT COLOR="#0000ff">q
</FONT><FONT COLOR="#000000">}</FONT>Result: USER>d ##class(Scratch.test).ClassVsInst() Cache for Windows (x86-64) 2018.1 dummyClass10* total time = .328227 avg time = .000000328227 dummyClass10 total time = .27655 avg time = .00000027655 dummyInst10 total time = .259913 avg time = .000000259913 dummyClass5* total time = .286983 avg time = .000000286983 dummyClass5 total time = .25666 avg time = .00000025666 dummyInst5 total time = .240312 avg time = .000000240312 dummyClassNull* total time = .274406 avg time = .000000274406 dummyClassNull total time = .250926 avg time = .000000250926 dummyInstNull total time = .234486 avg time = .000000234486 XdummyClass10 total time = .312917 avg time = .000000312917 XdummyInst10 total time = .264871 avg time = .000000264871 XdummyClass5 total time = .286985 avg time = .000000286985 XdummyInst5 total time = .238557 avg time = .000000238557 XdummyClassNull total time = .278684 avg time = .000000278684 XdummyInstNull total time = .236815 avg time = .000000236815
Class Test.RegObjTest Extends %RegisteredObject [ Final ]
{
ClassMethod NewMethod1() [ Final, NotInheritable ]
{
w "Neeravcxfdfd"
}
}
Procedureblock =1
means ALL local variables except call parameters and %variables move to stack
and return when you return from your method (=procedure)
see Summary on Local Variable Scoping for more
this memory operation is not free but nothing to get a headache upon
Vitaliy, thanks for the contribution. It seems that it ruins another myth, that Xecute is always slower than $[class]method. I've slightly reformatted an output of your ClassVsInst() method just to make it easier to compare results. Here are mine (using i5-4460 3.20 GHz):
USER>d ##class(Scratch.test).ClassVsInst(1e7) Cache for Windows (x86-64) 2017.2.2 dummyClass10* total time = 2.669215 avg time = .0000002669215 dummyClass10 total time = 2.375893 avg time = .0000002375893 XdummyClass10 total time = 2.676997 avg time = .0000002676997 dummyInst10 total time = 2.221366 avg time = .0000002221366 XdummyInst10 total time = 2.276357 avg time = .0000002276357 dummyClass5* total time = 2.540907 avg time = .0000002540907 dummyClass5 total time = 2.232347 avg time = .0000002232347 XdummyClass5 total time = 2.541123 avg time = .0000002541123 dummyInst5 total time = 2.070013 avg time = .0000002070013 XdummyInst5 total time = 2.049437 avg time = .0000002049437 dummyClassNull* total time = 2.362451 avg time = .0000002362451 dummyClassNull total time = 2.097653 avg time = .0000002097653 XdummyClassNull total time = 2.352748 avg time = .0000002352748 dummyInstNull total time = 2.018773 avg time = .0000002018773 XdummyInstNull total time = 2.056379 avg time = .0000002056379
It seems that Xecute is (not surprisingly) very close to $classmethod and usually slower than $method. But what are we talking about? The difference is about several nanoseconds per call only.
Of course, if your utility classes are all ABSTRACT it is pure code. As any .MAC, just easier to read.
OREF is just a special data type (object pointer) and not better or worse than any other variable.
I 'd guess variable scoping and procedure block has much more (microscopic) influence on performance.
My personal preference is to have only code tightly related to stored date in "object"-classes.
Anything else outside that is not only related to this class.
I completely agree with you.
Objects should be instantiated only when they are relevant.
Calling object methods where it's possible to call class methods makes code harder to read.
Well, how I would dive into this issue.
- Run %SYS.MONLBL in production, for a relevant time gap, at least 1 hour. You can filter it by classes which you care, and get the only line counts, to decrease impact on speed.
- So, you can collect summary time for all such Methods.
- Change a few of them to the new way as a ClassMethod, from MONLBL you can find the list of frequently used ones. So, will be easy to find what to change.
- Run %SYS.MONLBL with the same conditions as in the first time.
- Compare results.
- Decide
Of course, this way not so easy to realize, and depends on how you deploy code in production. Or maybe it even possible to measure in the testing environment.
Dear colleagues,
Thank you for paying so much attention to this tiny question. Maybe it was too tiny formulated: I should mention that objects instantiation impact is beyond the scope of the question as all of them are instantiated once; correspondent OREFs are stored in global scope variables for "public" use.
Going deep inside with %SYS.MONLBL is possible, while I'm too lazy to do it having no real performance problem. So, I've wrote several dummy methods, doubling instance and class ones, with different numbers of formal arguments, from 0 to 10. Here is the code I managed to write.
Class Scratch.test Extends %Library.RegisteredObject [ ProcedureBlock ]ClassMethod dummyClassNull() As %String{
q 1}Method dummyInstNull() As %String{
q 1}ClassMethod dummyClass5(a1, a2, a3, a4, a5) As %String{
q 1}Method dummyInst5(a1, a2, a3, a4, a5) As %String{
q 1}ClassMethod dummyClass10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) As %String{
q 1}Method dummyInst10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) As %String{
q 1}}My testing routine was:
ClassVsInst
s p1="пропоывшыщзшвыщшв"
s p2="гшщыгвыовлдыовдьыовдлоыдлв"
s p3="widuiowudoiwudoiwudoiwud"
s p4="прпроыпворыпворыпворыпв"
s p5="uywyiusywisywzxbabzjhagjЭ"
s p6="пропоывшыщзшвыщшв"
s p7="гшщыгвыовлдыовдьыовдлоыдлв"
s p8="widuiowudoiwudoiwudoiwud"
s p9="прпроыпворыпворыпворыпв"
s p10="uywyiusywisywzxbabzjhagjЭ"
d run^zmawr("s sc=##class(Scratch.test).dummyClass10(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)",1000000,"dummyClass10 "_$p($zv,"(Build"))
n st s st=##class(Scratch.test).%New() d run^zmawr("s sc=st.dummyInst10(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)",1000000,"dummyInst10 "_$p($zv,"(Build"))
s st=""
d run^zmawr("s sc=##class(Scratch.test).dummyClass5(p1,p2,p3,p4,p5)",1000000,"dummyClass5 "_$p($zv,"(Build"))
n st s st=##class(Scratch.test).%New() d run^zmawr("s sc=st.dummyInst5(p1,p2,p3,p4,p5)",1000000,"dummyInst5 "_$p($zv,"(Build"))
s st=""
d run^zmawr("s sc=##class(Scratch.test).dummyClassNull()",1000000,"dummyClassNull "_$p($zv,"(Build"))
n st s st=##class(Scratch.test).%New() d run^zmawr("s sc=st.dummyInstNull()",1000000,"dummyInstNull "_$p($zv,"(Build"))
q
run(what, n, comment) ; execute line 'what' 'n' times
n i s n=$g(n,1)
s comment=$g(comment,"********** "_what_" "_n_" run(s) **********")
w comment,!
s zzh0=$zh
f i=1:1:n x what
s zzdt=$zh-zzh0 w "total time = "_zzdt_" avg time = "_(zzdt/n),!
q
The results were:
USER>d ClassVsInst^zmawr dummyClass10 Cache for Windows (x86-64) 2017.2.2 total time = .377751 avg time = .000000377751 dummyInst10 Cache for Windows (x86-64) 2017.2.2 total time = .338336 avg time = .000000338336 dummyClass5 Cache for Windows (x86-64) 2017.2.2 total time = .335734 avg time = .000000335734 dummyInst5 Cache for Windows (x86-64) 2017.2.2 total time = .280145 avg time = .000000280145 dummyClassNull Cache for Windows (x86-64) 2017.2.2 total time = .256858 avg time = .000000256858 dummyInstNull Cache for Windows (x86-64) 2017.2.2 total time = .225813 avg time = .000000225813
So, despite my expectations, oref.Method() call turned to be quicker than its ##class(myClass).myMethod() analogue. As there is only less than microsecond effect per call, I don't see any reason for refactoring.