diff --git a/pyqtgraph/graphicsItems/GraphicsItem.py b/pyqtgraph/graphicsItems/GraphicsItem.py
index e34086bdb0e6529fef3902592042809ffd219130..5c941dae1e49edd12fd3b1fbd43c6dd2479e2ebb 100644
--- a/pyqtgraph/graphicsItems/GraphicsItem.py
+++ b/pyqtgraph/graphicsItems/GraphicsItem.py
@@ -3,29 +3,9 @@ from ..GraphicsScene import GraphicsScene
 from ..Point import Point
 from .. import functions as fn
 import weakref
-from ..pgcollections import OrderedDict
-import operator, sys
+import operator
+from pyqtgraph.lru_cache import LRUCache
 
-class FiniteCache(OrderedDict):
-    """Caches a finite number of objects, removing
-    least-frequently used items."""
-    def __init__(self, length):
-        self._length = length
-        OrderedDict.__init__(self)
-        
-    def __setitem__(self, item, val):
-        self.pop(item, None) # make sure item is added to end
-        OrderedDict.__setitem__(self, item, val) 
-        while len(self) > self._length:
-            del self[list(self.keys())[0]]
-        
-    def __getitem__(self, item):
-        val = OrderedDict.__getitem__(self, item)
-        del self[item]
-        self[item] = val  ## promote this key        
-        return val
-        
-        
 
 class GraphicsItem(object):
     """
@@ -38,7 +18,7 @@ class GraphicsItem(object):
 
     The GraphicsView system places a lot of emphasis on the notion that the graphics within the scene should be device independent--you should be able to take the same graphics and display them on screens of different resolutions, printers, export to SVG, etc. This is nice in principle, but causes me a lot of headache in practice. It means that I have to circumvent all the device-independent expectations any time I want to operate in pixel coordinates rather than arbitrary scene coordinates. A lot of the code in GraphicsItem is devoted to this task--keeping track of view widgets and device transforms, computing the size and shape of a pixel in local item coordinates, etc. Note that in item coordinates, a pixel does not have to be square or even rectangular, so just asking how to increase a bounding rect by 2px can be a rather complex task.
     """
-    _pixelVectorGlobalCache = FiniteCache(100)
+    _pixelVectorGlobalCache = LRUCache(100, 70)
     
     def __init__(self, register=True):
         if not hasattr(self, '_qtBaseClass'):
diff --git a/pyqtgraph/lru_cache.py b/pyqtgraph/lru_cache.py
new file mode 100644
index 0000000000000000000000000000000000000000..862e956add2aa82b86ac3dc34802d3d77c789da2
--- /dev/null
+++ b/pyqtgraph/lru_cache.py
@@ -0,0 +1,116 @@
+import operator
+import sys
+import itertools
+
+
+_IS_PY3 = sys.version_info[0] == 3
+
+class LRUCache(object):
+    '''
+    This LRU cache should be reasonable for short collections (until around 100 items), as it does a
+    sort on the items if the collection would become too big (so, it is very fast for getting and
+    setting but when its size would become higher than the max size it does one sort based on the
+    internal time to decide which items should be removed -- which should be Ok if the resize_to
+    isn't too close to the max_size so that it becomes an operation that doesn't happen all the
+    time).
+    '''
+
+    def __init__(self, max_size=100, resize_to=70):
+        '''
+        :param int max_size:
+            This is the maximum size of the cache. When some item is added and the cache would become
+            bigger than this, it's resized to the value passed on resize_to.
+            
+        :param int resize_to:
+            When a resize operation happens, this is the size of the final cache.
+        '''
+        assert resize_to < max_size
+        self.max_size = max_size
+        self.resize_to = resize_to
+        self._counter = 0
+        self._dict = {}
+        if _IS_PY3:
+            self._next_time = itertools.count(0).__next__
+        else:
+            self._next_time = itertools.count(0).next
+
+    def __getitem__(self, key):
+        item = self._dict[key]
+        item[2] = self._next_time()
+        return item[1]
+
+    def __len__(self):
+        return len(self._dict)
+
+    def __setitem__(self, key, value):
+        item = self._dict.get(key)
+        if item is None:
+            if len(self._dict) + 1 > self.max_size:
+                self._resize_to()
+            
+            item = [key, value, self._next_time()]
+            self._dict[key] = item
+        else:
+            item[1] = value
+            item[2] = self._next_time()
+            
+    def __delitem__(self, key):
+        del self._dict[key]
+        
+    def get(self, key, default=None):
+        try:
+            return self[key]
+        except KeyError:
+            return default
+        
+    def clear(self):
+        self._dict.clear()
+ 
+    if _IS_PY3:
+        def values(self):
+            return [i[1] for i in self._dict.values()]
+        
+        def keys(self):
+            return [x[0] for x in self._dict.values()]
+        
+        def _resize_to(self):
+            ordered = sorted(self._dict.values(), key=operator.itemgetter(2))[:self.resize_to]
+            for i in ordered:
+                del self._dict[i[0]]
+                
+        def iteritems(self, access_time=False):
+            '''
+            :param bool access_time:
+                If True sorts the returned items by the internal access time.
+            '''
+            if access_time:
+                for x in sorted(self._dict.values(), key=operator.itemgetter(2)):
+                    yield x[0], x[1]
+            else:
+                for x in self._dict.items():
+                    yield x[0], x[1]
+                    
+    else:
+        def values(self):
+            return [i[1] for i in self._dict.itervalues()]
+        
+        def keys(self):
+            return [x[0] for x in self._dict.itervalues()]
+            
+        
+        def _resize_to(self):
+            ordered = sorted(self._dict.itervalues(), key=operator.itemgetter(2))[:self.resize_to]
+            for i in ordered:
+                del self._dict[i[0]]
+                
+        def iteritems(self, access_time=False):
+            '''
+            :param bool access_time:
+                If True sorts the returned items by the internal access time.
+            '''
+            if access_time:
+                for x in sorted(self._dict.itervalues(), key=operator.itemgetter(2)):
+                    yield x[0], x[1]
+            else:
+                for x in self._dict.iteritems():
+                    yield x[0], x[1]
diff --git a/tests/test.py b/tests/test.py
index f24a7d42b8c1c44366415cc13229a17c5b541a25..9821f8212447f2bd8491122de325610ca495227d 100644
--- a/tests/test.py
+++ b/tests/test.py
@@ -5,4 +5,54 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')
 
 ## all tests should be defined with this class so we have the option to tweak it later.
 class TestCase(unittest.TestCase):
-    pass
\ No newline at end of file
+        
+    def testLRU(self):
+        from pyqtgraph.lru_cache import LRUCache
+        lru = LRUCache(2, 1)
+
+        def CheckLru():
+            lru[1] = 1
+            lru[2] = 2
+            lru[3] = 3
+
+            self.assertEqual(2, len(lru))
+            self.assertSetEqual(set([2, 3]), set(lru.keys()))
+            self.assertSetEqual(set([2, 3]), set(lru.values()))
+
+            lru[2] = 2
+            self.assertSetEqual(set([2, 3]), set(lru.values()))
+            
+            lru[1] = 1
+            self.assertSetEqual(set([2, 1]), set(lru.values()))
+
+            #Iterates from the used in the last access to others based on access time.
+            self.assertEqual([(2, 2), (1, 1)], list(lru.iteritems(access_time=True)))
+            lru[2] = 2
+            self.assertEqual([(1, 1), (2, 2)], list(lru.iteritems(access_time=True)))
+
+            del lru[2]
+            self.assertEqual([(1, 1), ], list(lru.iteritems(access_time=True)))
+
+            lru[2] = 2
+            self.assertEqual([(1, 1), (2, 2)], list(lru.iteritems(access_time=True)))
+
+            _a = lru[1]
+            self.assertEqual([(2, 2), (1, 1)], list(lru.iteritems(access_time=True)))
+
+            _a = lru[2]
+            self.assertEqual([(1, 1), (2, 2)], list(lru.iteritems(access_time=True)))
+
+            self.assertEqual(lru.get(2), 2)
+            self.assertEqual(lru.get(3), None)
+            self.assertEqual([(1, 1), (2, 2)], list(lru.iteritems(access_time=True)))
+
+            lru.clear()
+            self.assertEqual([], list(lru.iteritems()))
+
+        CheckLru()
+
+        # Check it twice...
+        CheckLru()
+
+if __name__ == '__main__':
+    unittest.main()
\ No newline at end of file