Skip to content

Commit fa533dd

Browse files
updated tests
1 parent 4c3b76c commit fa533dd

File tree

6 files changed

+31
-32
lines changed

6 files changed

+31
-32
lines changed

README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
This project is a bit of an experiment and involves 3 different LRU Cache implementations. One uses a min heap (often used in priority queues) instead of an OrderedDict, the second one uses the built-in OrderedDict from the collections package, and the last one uses my own simple implementation of an OrderedDict.
55

66
**Observations**:
7-
All three LRU Caches have the same tests. I ran some tests for scale with a capacity of 500 000 and another with a capacity of 5 000 000 elements in the cache. Even though the min heap has a Big O(log n) for inserts, updates and deletes, it is still slightly faster than both OrderedDict implementations, which should technically be Big O(1). My hypothesis is that this is so because the dictionary needs to rehash everything every time an insert goes over the bucket limit in the hash table.
7+
All three LRU Caches have the same tests. I ran some tests for scale with a capacity of 5 000 000 elements in the cache and added an additional 500 002 elements. Obviously, the min heap has a Big O(log n) for inserts, updates and deletes, so it is much slower than the OrderedDict, which has a Big O(1). That said, the min heap is actually slightly faster until you reach the cache's capacity.
88

9-
| Capacity | Min Heap | OrderedDict | MyOrderedDict |
10-
|:----------:|:---------:|:-------------:|:---------------:|
11-
| 500 000 | 4.675s | 4.976s | 5.756s |
12-
| 5 000 000 | 47.626s | 52.375s | 59.921s |
9+
Table for a 5 000 000 capacity cache
10+
| Number of inserted Elements | Min Heap | OrderedDict | MyOrderedDict |
11+
|:-----------------------------:|:------------:|:-------------:|:---------------:|
12+
| 5 000 000 | 47.626s | 52.375s | 59.921s |
13+
| 5 500 002 | 147.524s | 62.620s | 69.016s |
1314

1415
**Run tests**:
1516
To run the tests, you need to have nose installed. If you're on a UNIX-like system, you can run `easy_install nose` or `pip install nose`

lru_cache_min_heap/tests/lru_cache_scale_tests.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
class LRUCacheScaleTests(unittest.TestCase):
77
def setUp(self):
88
self.capacity = 5000000
9+
self.__num_over_capacity = 500002
910
self.lru_cache = LRUCache(self.capacity)
1011

11-
for i in xrange(1, self.capacity + 2):
12+
for i in xrange(1, self.capacity + self.__num_over_capacity):
1213
self.lru_cache.set('user' + str(i), 'user_number_' + str(i))
1314

1415
def tearDown(self):
@@ -19,19 +20,17 @@ def test_set_and_get(self):
1920
"""
2021
lru element should be user2 and user1 sould be removed.
2122
"""
22-
23-
self.assertEqual(self.lru_cache.get_lru_el(), self.lru_cache._cache_dict['user2'])
24-
self.lru_cache.get('user1')
23+
self.assertEqual(self.lru_cache.get_lru_el(), self.lru_cache._cache_dict['user' + str(self.__num_over_capacity)])
24+
self.lru_cache.get('user' + str(self.__num_over_capacity - 1))
2525

2626
def test_update(self):
2727
"""
2828
test update
2929
"""
30+
self.lru_cache.set('user' + str(self.__num_over_capacity + self.capacity/2), 'ANON_USER')
31+
self.assertTrue(self.lru_cache.get('user' + str(self.__num_over_capacity + self.capacity/2)) == 'ANON_USER')
3032

31-
self.lru_cache.set('user' + str(self.capacity/2), 'ANON_USER')
32-
self.assertTrue(self.lru_cache.get('user' + str(self.capacity/2)) == 'ANON_USER')
33-
34-
self.lru_cache.set('user2', 'USER2')
35-
self.assertEqual(self.lru_cache.get_lru_el(), self.lru_cache._cache_dict['user3'])
33+
self.lru_cache.set('user' + str(self.__num_over_capacity), 'USER' + str(self.__num_over_capacity))
34+
self.assertEqual(self.lru_cache.get_lru_el(), self.lru_cache._cache_dict['user' + str(self.__num_over_capacity + 1)])
3635

3736

lru_cache_my_ordered_dict/lru_cache.py

-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ def get_lru_el(self):
155155
def get_dict(self):
156156
return self._cache_dict
157157

158-
159158
lru_cache = LRUCache(3)
160159

161160
lru_cache.set("user1", "teme")

lru_cache_my_ordered_dict/tests/lru_cache_scale_tests.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
class LRUCacheScaleTests(unittest.TestCase):
77
def setUp(self):
88
self.capacity = 5000000
9+
self.__num_over_capacity = 500002
910
self.lru_cache = LRUCache(self.capacity)
1011

11-
for i in xrange(1, self.capacity + 2):
12+
for i in xrange(1, self.capacity + self.__num_over_capacity):
1213
self.lru_cache.set('user' + str(i), 'user_number_' + str(i))
1314

1415
def tearDown(self):
@@ -19,18 +20,17 @@ def test_set_and_get(self):
1920
"""
2021
lru element should be user2 and user1 sould be removed.
2122
"""
22-
self.assertEqual(self.lru_cache.get_lru_el(), 'user2')
23-
self.lru_cache.get('user1')
23+
self.assertEqual(self.lru_cache.get_lru_el(), 'user' + str(self.__num_over_capacity))
24+
self.lru_cache.get('user' + str(self.__num_over_capacity - 1))
2425

2526
def test_update(self):
2627
"""
2728
test update
2829
"""
30+
self.lru_cache.set('user' + str(self.__num_over_capacity + self.capacity/2), 'ANON_USER')
31+
self.assertTrue(self.lru_cache.get('user' + str(self.__num_over_capacity + self.capacity/2)) == 'ANON_USER')
2932

30-
self.lru_cache.set('user' + str(self.capacity/2), 'ANON_USER')
31-
self.assertTrue(self.lru_cache.get('user' + str(self.capacity/2)) == 'ANON_USER')
32-
33-
self.lru_cache.set('user2', 'USER2')
34-
self.assertEqual(self.lru_cache.get_lru_el(), 'user3')
33+
self.lru_cache.set('user' + str(self.__num_over_capacity), 'USER' + str(self.__num_over_capacity))
34+
self.assertEqual(self.lru_cache.get_lru_el(), 'user' + str(self.__num_over_capacity + 1))
3535

3636

lru_cache_ordered_dict/lru_cache.py

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def get_lru_el(self):
4545
def get_dict(self):
4646
return self._cache_dict
4747

48-
4948
lru_cache = LRUCache(3)
5049

5150
lru_cache.set("user1", "teme")

lru_cache_ordered_dict/tests/lru_cache_scale_tests.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from lru_cache import LRUCache
55

66
class LRUCacheScaleTests(unittest.TestCase):
7+
78
def setUp(self):
89
self.capacity = 5000000
10+
self.__num_over_capacity = 500002
911
self.lru_cache = LRUCache(self.capacity)
1012

11-
for i in xrange(1, self.capacity + 2):
13+
for i in xrange(1, self.capacity + self.__num_over_capacity):
1214
self.lru_cache.set('user' + str(i), 'user_number_' + str(i))
1315

1416
def tearDown(self):
@@ -19,18 +21,17 @@ def test_set_and_get(self):
1921
"""
2022
lru element should be user2 and user1 sould be removed.
2123
"""
22-
self.assertEqual(self.lru_cache.get_lru_el(), 'user2')
23-
self.lru_cache.get('user1')
24+
self.assertEqual(self.lru_cache.get_lru_el(), 'user' + str(self.__num_over_capacity))
25+
self.lru_cache.get('user' + str(self.__num_over_capacity - 1))
2426

2527
def test_update(self):
2628
"""
2729
test update
2830
"""
31+
self.lru_cache.set('user' + str(self.__num_over_capacity + self.capacity/2), 'ANON_USER')
32+
self.assertTrue(self.lru_cache.get('user' + str(self.__num_over_capacity + self.capacity/2)) == 'ANON_USER')
2933

30-
self.lru_cache.set('user' + str(self.capacity/2), 'ANON_USER')
31-
self.assertTrue(self.lru_cache.get('user' + str(self.capacity/2)) == 'ANON_USER')
32-
33-
self.lru_cache.set('user2', 'USER2')
34-
self.assertEqual(self.lru_cache.get_lru_el(), 'user3')
34+
self.lru_cache.set('user' + str(self.__num_over_capacity), 'USER' + str(self.__num_over_capacity))
35+
self.assertEqual(self.lru_cache.get_lru_el(), 'user' + str(self.__num_over_capacity + 1))
3536

3637

0 commit comments

Comments
 (0)