OOPMacro.jl icon indicating copy to clipboard operation
OOPMacro.jl copied to clipboard

got dot access working \o/

Open amanica opened this issue 6 years ago • 6 comments

Hi, I've not tested this much but it looks like I got the dot method access working eg.: @test s1.fun1(1, 2, z=3) == 6

let me know what you think :)

amanica avatar May 21 '19 22:05 amanica

This is nice! But I wonder how much overhead that costs. Because we might add a lot of branching in an instance function where you might keep referring to self.something. It would be nice to check its overhead in (1) field reference (2) lightweight functions and (3) heavy duty functions compared with the running time without this getproperty overloading implementation.

If there's an obvious overhead, then we should turn off this behaviour by default and have a mechanism to enable it (either by adding a function enableObjFnCall in the module or add an optional argument to the @class macro).

ipod825 avatar May 22 '19 05:05 ipod825

This is nice! But I wonder how much overhead that costs. Because we might add a lot of branching in an instance function where you might keep referring to self.something.

From what I read it should be fine: https://discourse.julialang.org/t/how-to-use-getproperty-setproperty/16033/3

It would be nice to check its overhead in

I agree, I'll write some checks and let you know. (I made it optional so-long)

amanica avatar May 22 '19 22:05 amanica

Try catch should reduce the overhead

                  try
                    getfield(self, name)
                  catch
                    (args...; kwargs...)->eval(:(\$name(\$self, \$args...; \$kwargs...)))
                  end

But it's still a large overhead.

ipod825 avatar May 24 '19 03:05 ipod825

Also, instead of having an additional args to @class, a function in the module that switches on/off a global variable would be a better idea as the user don't need to change every class definition in case he/she wants to switch between two mode (though in any case, the function calling part still requires change).

ipod825 avatar May 24 '19 03:05 ipod825

isdefined seems to trigger the inline compilation optimation. That's nice. However, it doesn't seem to help for function calls. Changing the test case to:

bg["DotOpr"]["get_field1"] = @benchmarkable o.fun1(1) setup=(o = B1DotOpr(rand(Int)))
bg["NoDotOpr"]["get_field1"] = @benchmarkable fun1(o, 1) setup=(o = B1NoDotOpr(rand(Int)))

We still get a very large latency. In fact, I doubt that this is not even caused by the branch, as if I changed dotAccStr to:

    dotAccStr = """
        function Base.getproperty(self::$clsName, name::Symbol)
            (args...; kwargs...)->eval(:(\$name(\$self, \$args...; \$kwargs...)))                                         
        end
        """

making dot operator works only for function calls, I got pretty much the same latency on the modified test case shown above, indicating that it's the creation of the unnamed function that causes the great latency. Unless we have some remedy to ask the compiler not to recompile an unnamed function every time, I don't think there is a solution to this problem. Caching the unnamed function in OOPMacro module space might be a direction to go.

ipod825 avatar May 31 '19 00:05 ipod825

Cool I'll look at the function call next :)

I check if in clsFnNameList so that if it is not in our list I want it to default to normal behaviour (is there a better way to check?). This gives a consistent error for myClass.invalidfield and maybe there are other dot operation use cases I have not thought about.

amanica avatar May 31 '19 06:05 amanica