Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cs] implement dynamic version of methods that accept type parameter in the generic interface #4475

Closed
nadako opened this issue Aug 10, 2015 · 4 comments · Fixed by #11551
Closed
Assignees
Labels
Milestone

Comments

@nadako
Copy link
Member

nadako commented Aug 10, 2015

Just an idea. Suppose we have:

class A<T> {
    public function new() {}
    public function f(v:T) {}
}

Currently this generates an interface for use as A<Dynamic>:

[global::haxe.lang.GenericInterface(typeof(global::A<object>))]
public interface A : global::haxe.lang.IHxObject, global::haxe.lang.IGenericObject {
    object A_cast<T_c>();
}

As we can see, it doesn't contain the f method because it uses type parameter which is not available in the interface, so the call to A<Dynamic>.f will generate a heavy dynamic call:

global::haxe.lang.Runtime.callField(v, "f", 102, new global::Array<object>(new object[]{10}));

How about we add a dynamic version of parametrized method to the interface, i.e.:

public interface A : global::haxe.lang.IHxObject, global::haxe.lang.IGenericObject {
    object A_cast<T_c>();
    void __hx_f(object v);
}

and implement that in the actual class that will do proper casting:

public class A<T> : global::haxe.lang.HxObject, global::A {
    public void f(T v) {
        // ...
    }
    public void __hx_f(object v) {
        this.f((T)v);
    }
}

and at the call site, A<Dynamic>.f will be generated a lot prettier:

v.__hx_f(10);

Are there any potential problems with that approach? cc @waneck

I wonder how hxcpp handles that btw.

@waneck
Copy link
Member

waneck commented Aug 10, 2015

I've thought about that, and the only reason I haven't implemented this is due to code size. I've always been trying to find a good balance between performance and code size. Let me know your thoughts about this

@nadako
Copy link
Member Author

nadako commented Aug 10, 2015

Are we talking about IL code size or just generated C#? Don't C# compilers have some kind of DCE to remove unused code?

If it's about generated C#, I can understand the point about it being concise not to scare newcomers, but still IMO performance is always more important. Actually, I think it would be great to have some document that describes what code is generated and the reasoning behind that, for those who love nitpicking generated code.

@vroad
Copy link
Contributor

vroad commented Nov 18, 2016

@nadako C# compiler cannot remove unused code just because it looks like it's not used in current assembly. It could be used via reflection, or maybe used from other assemblies.

If code size is a concern, we may need to have a haxedef that disables interface generation globally, and metadata that does the same thing with per-class basis.

@Simn Simn modified the milestones: 3.4, 4.0 Jan 9, 2017
@nadako
Copy link
Member Author

nadako commented Mar 23, 2017

Okay, let's implement stuff with performance in mind first, then look how we can reduce code size. I see e.g. Unity3D now have an unused bytecode stripper, Java's ProGuard hopefully will do a good job removing unused bytecode as well. And finally, we could try stuffing all such transforms pre-DCE, so it can be removed naturally by Haxe compiler.

@Simn Simn modified the milestones: Release 4.0, Design Apr 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants