Skip to content

Instantly share code, notes, and snippets.

@leasunhy
Last active March 14, 2017 03:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leasunhy/45e47cabe3c39ff151782ee862920f13 to your computer and use it in GitHub Desktop.
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
// 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() + "'");
}
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()
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()
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()
####### 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