Reputation: 147
Recently, I tried some code about cache. I have 2 codes, 1st with using dictionary. second with using cache library. I dont understand why the time running is so different. I thought the second which used the cache library works the same as the first.
First: import time import datetime
class new():
def __init__(self):
self.cache = {}
def get_candy_price(self, candy_id):
# let's use a sleep to simulate the time your function spends trying to connect to
# the web service, 5 seconds will be enough.
time.sleep(5)
if candy_id % 2 not in self.cache:
if candy_id % 2 == 0:
self.cache[candy_id % 2] = 1.5
else:
self.cache[candy_id % 2] = 1
# let's pretend that the price returned by the web service is $1 for candies with a
# odd candy_id and $1,5 for candies with a even candy_id
return (datetime.datetime.now().strftime("%c"), self.cache[candy_id % 2])
# now, let's simulate 20 customers in your show.
# They are asking for candy with id 2 and candy with id 3...
for i in range(0,20):
n = new()
print(n.get_candy_price(2))
print(n.get_candy_price(3))
Since everyone wants output:
Output:
('Thu Oct 25 16:14:27 2018', 1.5)
('Thu Oct 25 16:14:32 2018', 1)
('Thu Oct 25 16:14:37 2018', 1.5)
('Thu Oct 25 16:14:42 2018', 1)
('Thu Oct 25 16:14:47 2018', 1.5)
('Thu Oct 25 16:14:52 2018', 1)
('Thu Oct 25 16:14:57 2018', 1.5)
('Thu Oct 25 16:15:02 2018', 1)
('Thu Oct 25 16:15:07 2018', 1.5)
('Thu Oct 25 16:15:12 2018', 1)
('Thu Oct 25 16:15:17 2018', 1.5)
('Thu Oct 25 16:15:22 2018', 1)
('Thu Oct 25 16:15:27 2018', 1.5)
('Thu Oct 25 16:15:32 2018', 1)
('Thu Oct 25 16:15:37 2018', 1.5)
('Thu Oct 25 16:15:42 2018', 1)
('Thu Oct 25 16:15:47 2018', 1.5)
('Thu Oct 25 16:15:52 2018', 1)
('Thu Oct 25 16:15:57 2018', 1.5)
('Thu Oct 25 16:16:02 2018', 1)
('Thu Oct 25 16:16:07 2018', 1.5)
('Thu Oct 25 16:16:12 2018', 1)
('Thu Oct 25 16:16:17 2018', 1.5)
('Thu Oct 25 16:16:22 2018', 1)
('Thu Oct 25 16:16:27 2018', 1.5)
('Thu Oct 25 16:16:32 2018', 1)
('Thu Oct 25 16:16:37 2018', 1.5)
('Thu Oct 25 16:16:42 2018', 1)
('Thu Oct 25 16:16:47 2018', 1.5)
('Thu Oct 25 16:16:52 2018', 1)
('Thu Oct 25 16:16:57 2018', 1.5)
('Thu Oct 25 16:17:02 2018', 1)
('Thu Oct 25 16:17:07 2018', 1.5)
('Thu Oct 25 16:17:12 2018', 1)
('Thu Oct 25 16:17:17 2018', 1.5)
('Thu Oct 25 16:17:22 2018', 1)
('Thu Oct 25 16:17:27 2018', 1.5)
('Thu Oct 25 16:17:32 2018', 1)
('Thu Oct 25 16:17:37 2018', 1.5)
('Thu Oct 25 16:17:42 2018', 1)
real 3m20.145s
user 0m0.031s
sys 0m0.016s
Second:
import time
import datetime
from cachetools import cached, TTLCache # 1 - let's import the "cached" decorator and the "TTLCache" object from cachetools
cache = TTLCache(maxsize=100, ttl=300) # 2 - let's create the cache object.
@cached(cache)
def get_candy_price(candy_id):
# let's use a sleep to simulate the time your function spends trying to connect to
# the web service, 5 seconds will be enough.
time.sleep(5)
# let's pretend that the price returned by the web service is $1 for candies with a
# odd candy_id and $1,5 for candies with a even candy_id
price = 1.5 if candy_id % 2 == 0 else 1
return (datetime.datetime.now().strftime("%c"), price)
# now, let's simulate 20 customers in your show.
# They are asking for candy with id 2 and candy with id 3...
for i in range(0,20):
print(get_candy_price(2))
print(get_candy_price(3))
Output:
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
('Thu Oct 25 16:32:28 2018', 1.5)
('Thu Oct 25 16:32:33 2018', 1)
real 0m10.121s
user 0m0.031s
sys 0m0.016s
Can anyone show me the example of codes in a more understanding way for cache in second? For example, is it possible to change it to something more easy to see how the library runs for cache such like in first? The difference is about 3minutes differ.
My goal:
Is to understand the cache in python and so I tried to implement two different ways; one with library and another without. So cache with library is actually the same as making our own dictionary? So does it mean by cache it means we make a dictionary which act as look-up table?
Upvotes: 0
Views: 1929
Reputation: 568
You can always play with the code dude,
Your first example is poor to understand the cache mechanism, you are making
Your cache element is going to be formed again & again, as n = new() is re-initializing itself. Loosing all the cache. That is why it’s taking too long. Make it like,
n = new()
for i in range(0,20):
print(n.get_candy_price(2))
print(n.get_candy_price(3))
Another thing,
# let's use a sleep to simulate the time your function spends trying to connect to
# the web service, 5 seconds will be enough.
time.sleep(5)
You want to cache, Right? Then why this web call is getting called every time. This should always be called only when the answer is not in cache already, I am redefining your get_candy_price function,
def get_candy_price(self, candy_id):
# for observing the results
print (self.cache, candy_id)
if candy_id % 2 not in self.cache:
# as this wasn't already in cache
# let's use a sleep to simulate the time your function spends trying to connect to
# the web service, 1 seconds will be enough.
time.sleep(5)
if candy_id % 2 == 0:
self.cache[candy_id % 2] = 1.5
else:
self.cache[candy_id % 2] = 1
else:
# as we already have cached it
return self.cache[candy_id % 2]
return (datetime.datetime.now().strftime("%c"), self.cache[candy_id % 2])
In second example, play with ttl parameter
cache = TTLCache(maxsize=100, ttl=5)
Observe, it’s not going that fast now is it? It’s because you ttl(Time to live) parameter is caching the result for a certain amount of time. Google it for more!
Upvotes: 0
Reputation: 1740
Your first example sleep
for 5 seconds no matter it has cache or not, put that line into the if
, like
if candy_id % 2 not in self.cache:
time.sleep(5)
if candy_id % 2 == 0:
self.cache[candy_id % 2] = 1.5
else:
self.cache[candy_id % 2] = 1
Also the second example is caching the return-current-time. Therefore, the time part cannot be trusted.
Upvotes: 0