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

Generate more efficient code when pattern matching on a tuple #4783

Open
smarter opened this issue Jul 10, 2018 · 0 comments
Open

Generate more efficient code when pattern matching on a tuple #4783

smarter opened this issue Jul 10, 2018 · 0 comments

Comments

@smarter
Copy link
Member

smarter commented Jul 10, 2018

Given:

object Test {
  def test(x: Any, y: Any) = {
    (x, y) match {
      case (x: Int, y: Int) => 0
      case (x: String, y: String) => 1
      case _ => 2
    }
  }
}

We generate code that looks like this (when decompiled with cfr):

    public int test(Object x, Object y) {
        Object object;
        String string;
        String string2;
        Object object2;
        Tuple2 tuple2 = Tuple2$.MODULE$.apply(x, y);
        if (tuple2 == null) return 2;
        Object object3 = tuple2._1();
        Object object4 = tuple2._2();
        if (object3 instanceof Integer) {
            int n;
            int x2 = n = BoxesRunTime.unboxToInt((Object)object3);
            if (object4 instanceof Integer) {
                int n2;
                int y2 = n2 = BoxesRunTime.unboxToInt((Object)object4);
                return 0;
            }
            object = object4;
            object2 = object3;
        } else {
            object = object4;
            object2 = object3;
        }
        if (!(object2 instanceof String)) return 2;
        String x3 = string = (String)object2;
        if (!(object instanceof String)) return 2;
        String y3 = string2 = (String)object;
        return 1;
    }

scalac doesn't do much better by default, but scalac -optimise is very good:

    public int test(Object x, Object y) {
        int n = x instanceof Integer && y instanceof Integer ? 0 : (x instanceof String && y instanceof String ? 1 : 2);
        return n;
    }

It'd be interesting to see if we could get closer to this by improving the optimizations that are built-into the PatternMatcher phase. This would also help when destructuring, e.g. val (x, y) = (1, 2).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant