# HG changeset patch # User Paul Boddie # Date 1548455073 -3600 # Node ID caeae102e9dce4eb5389747179de994655a4af55 # Parent 6671fd0215a06e7295ffdf51e3e39e2092040050 Special-case float values in various operations for improved performance. diff -r 6671fd0215a0 -r caeae102e9dc lib/operator/augmented.py --- a/lib/operator/augmented.py Fri Jan 25 23:12:44 2019 +0100 +++ b/lib/operator/augmented.py Fri Jan 25 23:24:33 2019 +0100 @@ -3,7 +3,7 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2017 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2017, 2019 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -22,7 +22,8 @@ from operator.core import augassign from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \ int_and, int_or, int_xor, \ - is_int + is_int, \ + float_add, float_div, float_mul, float_pow, float_sub # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -36,6 +37,8 @@ def iadd(a, b): if is_int(a) and is_int(b): return int_add(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_add(a, b) return augassign(a, b, lambda a: a.__iadd__, lambda a: a.__add__, lambda b: b.__radd__) def iand_(a, b): @@ -46,6 +49,8 @@ def idiv(a, b): if is_int(a) and is_int(b): return int_div(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_div(a, b) return augassign(a, b, lambda a: a.__idiv__, lambda a: a.__div__, lambda b: b.__rdiv__) def ifloordiv(a, b): @@ -62,6 +67,8 @@ def imul(a, b): if is_int(a) and is_int(b): return int_mul(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_mul(a, b) return augassign(a, b, lambda a: a.__imul__, lambda a: a.__mul__, lambda b: b.__rmul__) def ior_(a, b): @@ -72,6 +79,8 @@ def ipow(a, b): if is_int(a) and is_int(b): return int_pow(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_pow(a, b) return augassign(a, b, lambda a: a.__ipow__, lambda a: a.__pow__, lambda b: b.__rpow__) def irshift(a, b): @@ -80,6 +89,8 @@ def isub(a, b): if is_int(a) and is_int(b): return int_sub(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_sub(a, b) return augassign(a, b, lambda a: a.__isub__, lambda a: a.__sub__, lambda b: b.__rsub__) def ixor(a, b): diff -r 6671fd0215a0 -r caeae102e9dc lib/operator/binary.py --- a/lib/operator/binary.py Fri Jan 25 23:12:44 2019 +0100 +++ b/lib/operator/binary.py Fri Jan 25 23:24:33 2019 +0100 @@ -3,7 +3,8 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017, + 2019 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,7 +24,8 @@ from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \ int_lshift, int_rshift, \ int_and, int_not, int_or, int_xor, \ - is_int + is_int, \ + float_add, float_div, float_mul, float_pow, float_sub # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -34,6 +36,8 @@ def add(a, b): if is_int(a) and is_int(b): return int_add(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_add(a, b) return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__) def and_(a, b): @@ -47,6 +51,8 @@ def div(a, b): if is_int(a) and is_int(b): return int_div(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_div(a, b) return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__) def floordiv(a, b): @@ -71,6 +77,8 @@ def mul(a, b): if is_int(a) and is_int(b): return int_mul(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_mul(a, b) return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__) def or_(a, b): @@ -81,6 +89,8 @@ def pow(a, b): if is_int(a) and is_int(b): return int_pow(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_pow(a, b) return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__) def rshift(a, b): @@ -91,6 +101,8 @@ def sub(a, b): if is_int(a) and is_int(b): return int_sub(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_sub(a, b) return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__) def xor(a, b): diff -r 6671fd0215a0 -r caeae102e9dc lib/operator/comparison.py --- a/lib/operator/comparison.py Fri Jan 25 23:12:44 2019 +0100 +++ b/lib/operator/comparison.py Fri Jan 25 23:24:33 2019 +0100 @@ -3,7 +3,8 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017, + 2019 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,7 +21,8 @@ """ from operator.core import binary_op -from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int +from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int, \ + float_eq, float_ge, float_gt, float_le, float_lt, float_ne # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -31,31 +33,43 @@ def eq(a, b): if is_int(a) and is_int(b): return int_eq(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_eq(a, b) return binary_op(a, b, lambda a: a.__eq__, lambda b: b.__eq__, False) def ge(a, b): if is_int(a) and is_int(b): return int_ge(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_ge(a, b) return binary_op(a, b, lambda a: a.__ge__, lambda b: b.__le__) def gt(a, b): if is_int(a) and is_int(b): return int_gt(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_gt(a, b) return binary_op(a, b, lambda a: a.__gt__, lambda b: b.__lt__) def le(a, b): if is_int(a) and is_int(b): return int_le(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_le(a, b) return binary_op(a, b, lambda a: a.__le__, lambda b: b.__ge__) def lt(a, b): if is_int(a) and is_int(b): return int_lt(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_lt(a, b) return binary_op(a, b, lambda a: a.__lt__, lambda b: b.__gt__) def ne(a, b): if is_int(a) and is_int(b): return int_ne(a, b) + elif a.__class__ is float and b.__class__ is float: + return float_ne(a, b) return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__, True) # vim: tabstop=4 expandtab shiftwidth=4 diff -r 6671fd0215a0 -r caeae102e9dc lib/operator/unary.py --- a/lib/operator/unary.py Fri Jan 25 23:12:44 2019 +0100 +++ b/lib/operator/unary.py Fri Jan 25 23:24:33 2019 +0100 @@ -3,7 +3,8 @@ """ Operator support. -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie +Copyright (C) 2010, 2013, 2015, 2016, 2017, + 2019 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,7 +21,7 @@ """ from operator.core import unary_op -from native.int import int_neg, int_not, is_int +from native import int_neg, int_not, is_int, float_neg # These functions defer method lookup by wrapping the attribute access in # lambda functions. Thus, the appropriate methods are defined locally, but no @@ -34,6 +35,8 @@ def neg(a): if is_int(a): return int_neg(a) + elif a.__class__ is float: + return float_neg(a) return unary_op(a, lambda a: a.__neg__) def not_(a): @@ -42,7 +45,7 @@ return not a def pos(a): - if is_int(a): + if is_int(a) or a.__class__ is float: return a return unary_op(a, lambda a: a.__pos__)