Last active
March 14, 2017 03:22
-
-
Save leasunhy/45e47cabe3c39ff151782ee862920f13 to your computer and use it in GitHub Desktop.
Benchmarking "select between an operator and its reflected version inline" and "use a helper method to do that" for voc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// skipping unrelated code | |
public static org.python.Object add(org.python.Object lhs, org.python.Object rhs) { | |
org.python.Object ret = org.python.types.NotImplementedType.NOT_IMPLEMENTED; | |
boolean subclassCase = lhs.type() != rhs.type() | |
&& ((org.python.types.Bool)org.Python.isinstance(rhs, lhs.type())).value; | |
if (subclassCase) { | |
try { | |
if ((ret = rhs.__radd__(lhs)) != org.python.types.NotImplementedType.NOT_IMPLEMENTED) | |
return ret; | |
} | |
catch (org.python.exceptions.AttributeError e) {} | |
} | |
if ((ret = lhs.__add__(rhs)) != org.python.types.NotImplementedType.NOT_IMPLEMENTED) | |
return ret; | |
if (!subclassCase) { | |
try { | |
if ((ret = rhs.__radd__(lhs)) != org.python.types.NotImplementedType.NOT_IMPLEMENTED) | |
return ret; | |
} | |
catch (org.python.exceptions.AttributeError e) {} | |
} | |
throw new org.python.exceptions.TypeError("unsupported operand type(s) for +: '" + lhs.typeName() + "' and '" + rhs.typeName() + "'"); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class A: | |
def __init__(self, val): | |
self.val = val | |
def __add__(self, other): | |
return self.val + other.val | |
class B(A): | |
def __init__(self, val): | |
self.val = val | |
def __radd__(self, other): | |
return self.val + other.val + 1 | |
def test(): | |
a = A(1) | |
b = A(2) | |
print(a + b) | |
# here repeats `print(a + b)` for 200 times | |
print(a + b) | |
if __name__ == "__main__": | |
test() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class A: | |
def __init__(self, val): | |
self.val = val | |
def __add__(self, other): | |
return self.val + other.val | |
class B(A): | |
def __init__(self, val): | |
self.val = val | |
def __radd__(self, other): | |
return self.val + other.val + 1 | |
def test(): | |
a = A(1) | |
b = B(2) | |
print(a + b) | |
print(b + a) | |
if __name__ == "__main__": | |
test() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class A: | |
def __init__(self, val): | |
self.val = val | |
def __add__(self, other): | |
return self.val + other.val | |
class B(A): | |
def __init__(self, val): | |
self.val = val | |
def __radd__(self, other): | |
return self.val + other.val + 1 | |
def test(): | |
a = A(1) | |
b = B(2) | |
print(a + b) | |
if __name__ == "__main__": | |
test() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####### skip unrelated code | |
@node_visitor | |
def visit_BinOp(self, node): | |
# expr left, operator op, expr right): | |
if isinstance(node.op, ast.Pow): | |
self.visit(node.left) | |
self.visit(node.right) | |
self.context.add_opcodes( | |
JavaOpcodes.ACONST_NULL(), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'__pow__', | |
args=['Lorg/python/Object;', 'Lorg/python/Object;'], | |
returns='Lorg/python/Object;' | |
), | |
) | |
else: | |
if isinstance(node.op, ast.Add): | |
# for benchmarking reflected operation logic | |
# approach 1: directly generate java opcode | |
left_name = "#BinOp-%s-lhs" % id(node) | |
right_name = "#BinOp-%s-rhs" % id(node) | |
self.visit(node.left) | |
self.context.add_opcodes( | |
ASTORE_name(left_name) | |
) | |
self.visit(node.right) | |
self.context.add_opcodes( | |
ASTORE_name(right_name) | |
) | |
self.context.add_opcodes( | |
ALOAD_name(left_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'type', | |
args=[], | |
returns='Lorg/python/types/Type;' | |
), | |
ALOAD_name(right_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'type', | |
args=[], | |
returns='Lorg/python/types/Type;' | |
), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IF_ACMPEQ), | |
) | |
self.context.add_opcodes( | |
JavaOpcodes.ICONST_0, ##### <- error here: TypeError: process() missing 1 required positional argument: 'context' | |
) | |
self.context.add_opcodes( | |
ELSE(), | |
) | |
self.context.add_opcodes( | |
ALOAD_name(right_name), | |
ALOAD_name(left_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'type', | |
args=[], | |
returns='Lorg/python/types/Type;' | |
), | |
JavaOpcodes.INVOKESTATIC( | |
'org/Python', | |
'isinstance', | |
args=['Lorg/python/Object;', 'Lorg/python/Object;'], | |
returns='Lorg/python/types/Bool;' | |
), | |
JavaOpcodes.GETFIELD( | |
'org/python/types/Bool', | |
'value', | |
'Z' | |
), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IFNE), | |
) | |
self.context.add_opcodes( | |
JavaOpcodes.ICONST_1, | |
) | |
self.context.add_opcodes( | |
ELSE(), | |
) | |
self.context.add_opcodes( | |
JavaOpcodes.ICONST_0, | |
) | |
self.context.add_opcodes( | |
END_IF(), | |
) | |
self.context.add_opcodes( | |
END_IF(), | |
) | |
self.context.add_opcodes( | |
ISTORE_name('#BinOp-%s-issubclasscase' % id(node)), | |
ILOAD_name('#BinOp-%s-issubclasscase' % id(node)), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IFNE), | |
) | |
self.context.add_opcodes( | |
ALOAD_name(right_name), | |
ALOAD_name(left_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'__radd__', | |
args=['Lorg/python/Object;'], | |
returns='Lorg/python/Object;' | |
), | |
JavaOpcodes.DUP(), | |
ASTORE_name('#BinOp-%s-radd' % id(node)), | |
JavaOpcodes.GETSTATIC('org/python/types/NotImplementedType', 'NOT_IMPLEMENTED', 'Lorg/python/Object;'), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IF_ACMPNE), | |
) | |
self.context.add_opcodes( | |
ALOAD_name('#BinOp-%s-radd' % id(node)), | |
free_name('#BinOp-%s-radd' % id(node)), | |
JavaOpcodes.ARETURN(), | |
) | |
self.context.add_opcodes( | |
END_IF() | |
) | |
self.context.add_opcodes( | |
END_IF() | |
) | |
self.context.add_opcodes( | |
ALOAD_name(left_name), | |
ALOAD_name(right_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'__add__', | |
args=['Lorg/python/Object;'], | |
returns='Lorg/python/Object;' | |
), | |
JavaOpcodes.DUP(), | |
ASTORE_name('#BinOp-%s-add' % id(node)), | |
JavaOpcodes.GETSTATIC('org/python/types/NotImplementedType', 'NOT_IMPLEMENTED', 'Lorg/python/Object;'), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IF_ACMPNE), | |
) | |
self.context.add_opcodes( | |
ALOAD_name('#BinOp-%s-add' % id(node)), | |
free_name('#BinOp-%s-add' % id(node)), | |
JavaOpcodes.ARETURN(), | |
) | |
self.context.add_opcodes( | |
END_IF() | |
) | |
self.context.add_opcodes( | |
ILOAD_name('#BinOp-%s-issubclasscase' % id(node)), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IFEQ), | |
) | |
self.context.add_opcodes( | |
ALOAD_name(right_name), | |
ALOAD_name(left_name), | |
JavaOpcodes.INVOKEINTERFACE( | |
'org/python/Object', | |
'__radd__', | |
args=['Lorg/python/Object;'], | |
returns='Lorg/python/Object;' | |
), | |
JavaOpcodes.DUP(), | |
ASTORE_name('#BinOp-%s-radd' % id(node)), | |
JavaOpcodes.GETSTATIC('org/python/types/NotImplementedType', 'NOT_IMPLEMENTED', 'Lorg/python/Object;'), | |
free_name('#BinOp-%s-issubclasscase' % id(node)), | |
) | |
self.context.add_opcodes( | |
IF([], JavaOpcodes.IF_ACMPNE), | |
) | |
self.context.add_opcodes( | |
ALOAD_name('#BinOp-%s-radd' % id(node)), | |
free_name('#BinOp-%s-radd' % id(node)), | |
JavaOpcodes.ARETURN(), | |
) | |
self.context.add_opcodes( | |
END_IF() | |
) | |
self.context.add_opcodes( | |
END_IF() | |
) | |
self.context.add_opcodes( | |
free_name('#BinOp-%s-issubclasscase' % id(node)), | |
free_name(left_name), | |
free_name(right_name), | |
) | |
# throw and handle exceptions | |
# approach 2: use static method for that purpose | |
# self.visit(node.left) | |
# self.visit(node.right) | |
# self.context.add_opcodes( | |
# JavaOpcodes.INVOKESTATIC( | |
# 'org/python/types/Object', | |
# 'add', | |
# args=[ | |
# 'Lorg/python/Object;', | |
# 'Lorg/python/Object;', | |
# ], | |
# returns='Lorg/python/Object;' | |
# ) | |
# ) | |
return | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment