Lichen

Changeset

873:caeae102e9dc
2019-01-25 Paul Boddie raw files shortlog changelog graph Special-case float values in various operations for improved performance. trailing-data
lib/operator/augmented.py (file) lib/operator/binary.py (file) lib/operator/comparison.py (file) lib/operator/unary.py (file)
     1.1 --- a/lib/operator/augmented.py	Fri Jan 25 23:12:44 2019 +0100
     1.2 +++ b/lib/operator/augmented.py	Fri Jan 25 23:24:33 2019 +0100
     1.3 @@ -3,7 +3,7 @@
     1.4  """
     1.5  Operator support.
     1.6  
     1.7 -Copyright (C) 2010, 2013, 2015, 2017 Paul Boddie <paul@boddie.org.uk>
     1.8 +Copyright (C) 2010, 2013, 2015, 2017, 2019 Paul Boddie <paul@boddie.org.uk>
     1.9  
    1.10  This program is free software; you can redistribute it and/or modify it under
    1.11  the terms of the GNU General Public License as published by the Free Software
    1.12 @@ -22,7 +22,8 @@
    1.13  from operator.core import augassign
    1.14  from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \
    1.15                     int_and, int_or, int_xor, \
    1.16 -                   is_int
    1.17 +                   is_int, \
    1.18 +                   float_add, float_div, float_mul, float_pow, float_sub
    1.19  
    1.20  # These functions defer method lookup by wrapping the attribute access in
    1.21  # lambda functions. Thus, the appropriate methods are defined locally, but no
    1.22 @@ -36,6 +37,8 @@
    1.23  def iadd(a, b):
    1.24      if is_int(a) and is_int(b):
    1.25          return int_add(a, b)
    1.26 +    elif a.__class__ is float and b.__class__ is float:
    1.27 +        return float_add(a, b)
    1.28      return augassign(a, b, lambda a: a.__iadd__, lambda a: a.__add__, lambda b: b.__radd__)
    1.29  
    1.30  def iand_(a, b):
    1.31 @@ -46,6 +49,8 @@
    1.32  def idiv(a, b):
    1.33      if is_int(a) and is_int(b):
    1.34          return int_div(a, b)
    1.35 +    elif a.__class__ is float and b.__class__ is float:
    1.36 +        return float_div(a, b)
    1.37      return augassign(a, b, lambda a: a.__idiv__, lambda a: a.__div__, lambda b: b.__rdiv__)
    1.38  
    1.39  def ifloordiv(a, b):
    1.40 @@ -62,6 +67,8 @@
    1.41  def imul(a, b):
    1.42      if is_int(a) and is_int(b):
    1.43          return int_mul(a, b)
    1.44 +    elif a.__class__ is float and b.__class__ is float:
    1.45 +        return float_mul(a, b)
    1.46      return augassign(a, b, lambda a: a.__imul__, lambda a: a.__mul__, lambda b: b.__rmul__)
    1.47  
    1.48  def ior_(a, b):
    1.49 @@ -72,6 +79,8 @@
    1.50  def ipow(a, b):
    1.51      if is_int(a) and is_int(b):
    1.52          return int_pow(a, b)
    1.53 +    elif a.__class__ is float and b.__class__ is float:
    1.54 +        return float_pow(a, b)
    1.55      return augassign(a, b, lambda a: a.__ipow__, lambda a: a.__pow__, lambda b: b.__rpow__)
    1.56  
    1.57  def irshift(a, b):
    1.58 @@ -80,6 +89,8 @@
    1.59  def isub(a, b):
    1.60      if is_int(a) and is_int(b):
    1.61          return int_sub(a, b)
    1.62 +    elif a.__class__ is float and b.__class__ is float:
    1.63 +        return float_sub(a, b)
    1.64      return augassign(a, b, lambda a: a.__isub__, lambda a: a.__sub__, lambda b: b.__rsub__)
    1.65  
    1.66  def ixor(a, b):
     2.1 --- a/lib/operator/binary.py	Fri Jan 25 23:12:44 2019 +0100
     2.2 +++ b/lib/operator/binary.py	Fri Jan 25 23:24:33 2019 +0100
     2.3 @@ -3,7 +3,8 @@
     2.4  """
     2.5  Operator support.
     2.6  
     2.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     2.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
     2.9 +              2019 Paul Boddie <paul@boddie.org.uk>
    2.10  
    2.11  This program is free software; you can redistribute it and/or modify it under
    2.12  the terms of the GNU General Public License as published by the Free Software
    2.13 @@ -23,7 +24,8 @@
    2.14  from native import int_add, int_div, int_mod, int_mul, int_pow, int_sub, \
    2.15                     int_lshift, int_rshift, \
    2.16                     int_and, int_not, int_or, int_xor, \
    2.17 -                   is_int
    2.18 +                   is_int, \
    2.19 +                   float_add, float_div, float_mul, float_pow, float_sub
    2.20  
    2.21  # These functions defer method lookup by wrapping the attribute access in
    2.22  # lambda functions. Thus, the appropriate methods are defined locally, but no
    2.23 @@ -34,6 +36,8 @@
    2.24  def add(a, b):
    2.25      if is_int(a) and is_int(b):
    2.26          return int_add(a, b)
    2.27 +    elif a.__class__ is float and b.__class__ is float:
    2.28 +        return float_add(a, b)
    2.29      return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__)
    2.30  
    2.31  def and_(a, b):
    2.32 @@ -47,6 +51,8 @@
    2.33  def div(a, b):
    2.34      if is_int(a) and is_int(b):
    2.35          return int_div(a, b)
    2.36 +    elif a.__class__ is float and b.__class__ is float:
    2.37 +        return float_div(a, b)
    2.38      return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__)
    2.39  
    2.40  def floordiv(a, b):
    2.41 @@ -71,6 +77,8 @@
    2.42  def mul(a, b):
    2.43      if is_int(a) and is_int(b):
    2.44          return int_mul(a, b)
    2.45 +    elif a.__class__ is float and b.__class__ is float:
    2.46 +        return float_mul(a, b)
    2.47      return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__)
    2.48  
    2.49  def or_(a, b):
    2.50 @@ -81,6 +89,8 @@
    2.51  def pow(a, b):
    2.52      if is_int(a) and is_int(b):
    2.53          return int_pow(a, b)
    2.54 +    elif a.__class__ is float and b.__class__ is float:
    2.55 +        return float_pow(a, b)
    2.56      return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__)
    2.57  
    2.58  def rshift(a, b):
    2.59 @@ -91,6 +101,8 @@
    2.60  def sub(a, b):
    2.61      if is_int(a) and is_int(b):
    2.62          return int_sub(a, b)
    2.63 +    elif a.__class__ is float and b.__class__ is float:
    2.64 +        return float_sub(a, b)
    2.65      return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__)
    2.66  
    2.67  def xor(a, b):
     3.1 --- a/lib/operator/comparison.py	Fri Jan 25 23:12:44 2019 +0100
     3.2 +++ b/lib/operator/comparison.py	Fri Jan 25 23:24:33 2019 +0100
     3.3 @@ -3,7 +3,8 @@
     3.4  """
     3.5  Operator support.
     3.6  
     3.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     3.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
     3.9 +              2019 Paul Boddie <paul@boddie.org.uk>
    3.10  
    3.11  This program is free software; you can redistribute it and/or modify it under
    3.12  the terms of the GNU General Public License as published by the Free Software
    3.13 @@ -20,7 +21,8 @@
    3.14  """
    3.15  
    3.16  from operator.core import binary_op
    3.17 -from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int
    3.18 +from native import int_eq, int_ge, int_gt, int_le, int_lt, int_ne, is_int, \
    3.19 +                   float_eq, float_ge, float_gt, float_le, float_lt, float_ne
    3.20  
    3.21  # These functions defer method lookup by wrapping the attribute access in
    3.22  # lambda functions. Thus, the appropriate methods are defined locally, but no
    3.23 @@ -31,31 +33,43 @@
    3.24  def eq(a, b):
    3.25      if is_int(a) and is_int(b):
    3.26          return int_eq(a, b)
    3.27 +    elif a.__class__ is float and b.__class__ is float:
    3.28 +        return float_eq(a, b)
    3.29      return binary_op(a, b, lambda a: a.__eq__, lambda b: b.__eq__, False)
    3.30  
    3.31  def ge(a, b):
    3.32      if is_int(a) and is_int(b):
    3.33          return int_ge(a, b)
    3.34 +    elif a.__class__ is float and b.__class__ is float:
    3.35 +        return float_ge(a, b)
    3.36      return binary_op(a, b, lambda a: a.__ge__, lambda b: b.__le__)
    3.37  
    3.38  def gt(a, b):
    3.39      if is_int(a) and is_int(b):
    3.40          return int_gt(a, b)
    3.41 +    elif a.__class__ is float and b.__class__ is float:
    3.42 +        return float_gt(a, b)
    3.43      return binary_op(a, b, lambda a: a.__gt__, lambda b: b.__lt__)
    3.44  
    3.45  def le(a, b):
    3.46      if is_int(a) and is_int(b):
    3.47          return int_le(a, b)
    3.48 +    elif a.__class__ is float and b.__class__ is float:
    3.49 +        return float_le(a, b)
    3.50      return binary_op(a, b, lambda a: a.__le__, lambda b: b.__ge__)
    3.51  
    3.52  def lt(a, b):
    3.53      if is_int(a) and is_int(b):
    3.54          return int_lt(a, b)
    3.55 +    elif a.__class__ is float and b.__class__ is float:
    3.56 +        return float_lt(a, b)
    3.57      return binary_op(a, b, lambda a: a.__lt__, lambda b: b.__gt__)
    3.58  
    3.59  def ne(a, b):
    3.60      if is_int(a) and is_int(b):
    3.61          return int_ne(a, b)
    3.62 +    elif a.__class__ is float and b.__class__ is float:
    3.63 +        return float_ne(a, b)
    3.64      return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__, True)
    3.65  
    3.66  # vim: tabstop=4 expandtab shiftwidth=4
     4.1 --- a/lib/operator/unary.py	Fri Jan 25 23:12:44 2019 +0100
     4.2 +++ b/lib/operator/unary.py	Fri Jan 25 23:24:33 2019 +0100
     4.3 @@ -3,7 +3,8 @@
     4.4  """
     4.5  Operator support.
     4.6  
     4.7 -Copyright (C) 2010, 2013, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     4.8 +Copyright (C) 2010, 2013, 2015, 2016, 2017,
     4.9 +              2019 Paul Boddie <paul@boddie.org.uk>
    4.10  
    4.11  This program is free software; you can redistribute it and/or modify it under
    4.12  the terms of the GNU General Public License as published by the Free Software
    4.13 @@ -20,7 +21,7 @@
    4.14  """
    4.15  
    4.16  from operator.core import unary_op
    4.17 -from native.int import int_neg, int_not, is_int
    4.18 +from native import int_neg, int_not, is_int, float_neg
    4.19  
    4.20  # These functions defer method lookup by wrapping the attribute access in
    4.21  # lambda functions. Thus, the appropriate methods are defined locally, but no
    4.22 @@ -34,6 +35,8 @@
    4.23  def neg(a):
    4.24      if is_int(a):
    4.25          return int_neg(a)
    4.26 +    elif a.__class__ is float:
    4.27 +        return float_neg(a)
    4.28      return unary_op(a, lambda a: a.__neg__)
    4.29  
    4.30  def not_(a):
    4.31 @@ -42,7 +45,7 @@
    4.32      return not a
    4.33  
    4.34  def pos(a):
    4.35 -    if is_int(a):
    4.36 +    if is_int(a) or a.__class__ is float:
    4.37          return a
    4.38      return unary_op(a, lambda a: a.__pos__)
    4.39