]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
_Timeout.__lt__ speedup 1729/head
authorDmitry Volodin <dv@nocproject.org>
Wed, 25 May 2016 22:17:38 +0000 (02:17 +0400)
committerDmitry Volodin <dv@nocproject.org>
Wed, 25 May 2016 22:17:38 +0000 (02:17 +0400)
One of our services uses a lots of callbacks (~15k per IOLoop) and performs massive network IO. During profiling we'd found that significant amount of time consumed in the _Timeout.__lt__ method. Current implementation constantly builds two tuples per comparison. Proposed one pre-builds tuple
during _Timeout creation. Its about ~40% faster.

In [1]: from tornado.ioloop import _Timeout, IOLoop
In [2]: io = IOLoop.current()
In [3]: t0 = _Timeout(io.time(), None, io)
In [4]: t1 = _Timeout(io.time(), None, io)
In [5]: %timeit t0 < t1
1000000 loops, best of 3: 587 ns per loop
In [6]: %timeit t0 < t1
1000000 loops, best of 3: 336 ns per loop

tornado/ioloop.py

index 0bcbd776001239189cf44c00d366352905a7aaed..d73e2712bc607a72080eaf543aa0eb72a7916f8e 100644 (file)
@@ -966,26 +966,24 @@ class _Timeout(object):
     """An IOLoop timeout, a UNIX timestamp and a callback"""
 
     # Reduce memory overhead when there are lots of pending callbacks
-    __slots__ = ['deadline', 'callback', 'tiebreaker']
+    __slots__ = ['deadline', 'callback', 'tdeadline']
 
     def __init__(self, deadline, callback, io_loop):
         if not isinstance(deadline, numbers.Real):
             raise TypeError("Unsupported deadline %r" % deadline)
         self.deadline = deadline
         self.callback = callback
-        self.tiebreaker = next(io_loop._timeout_counter)
+        self.tdeadline = (deadline, next(io_loop._timeout_counter))
 
     # Comparison methods to sort by deadline, with object id as a tiebreaker
     # to guarantee a consistent ordering.  The heapq module uses __le__
     # in python2.5, and __lt__ in 2.6+ (sort() and most other comparisons
     # use __lt__).
     def __lt__(self, other):
-        return ((self.deadline, self.tiebreaker) <
-                (other.deadline, other.tiebreaker))
+        return self.tdeadline < other.tdeadline
 
     def __le__(self, other):
-        return ((self.deadline, self.tiebreaker) <=
-                (other.deadline, other.tiebreaker))
+        return self.tdeadline <= other.tdeadline
 
 
 class PeriodicCallback(object):