我正在从PHP切换到Python + Django并寻找相当于PHP的“数组缓存”。
对于来自DB的小型数据集,如“类别”,这些数据集很少变化但经常访问我使用的是数组缓存。
http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/
它的概念是使用类别树生成PHP源,并且当操作码打开时,它就像将数据嵌入到应用程序源中一样。它是可以想象得最快的缓存,对于大负载非常有用。
Django手册(https://docs.djangoproject.com/en/1.4/topics/cache/)声明:
到目前为止,Django可用的最快,最有效的缓存类型,Memcached ..
所以问题是:
编辑:
正如答案所指出的,我可以使用repr(),这可以很容易地进行基准测试,因此我创建了一个简单的基准:
https://github.com/fsw/pythonCachesBenchmark
我本地机器上的输出是:
FIRST RUN
get_categories_from_db
6.57282209396
get_categories_from_memcached
(SET CACHE IN 0.000940)
4.88948512077
get_categories_from_pickledfile
(SET CACHE IN 0.000917)
2.87856888771
get_categories_from_pythonsrc
(SET CACHE IN 0.000489)
0.0930788516998
SECOND RUN
get_categories_from_db
6.63035202026
get_categories_from_memcached
4.60877108574
get_categories_from_pickledfile
2.87137699127
get_categories_from_pythonsrc
0.0903170108795
get_categories_from_pythonsrc是我正在讨论的PHP arraycache的简单实现:
def get_categories_from_pythonsrc():
if not os.path.exists('catcache.py'):
start = time.time()
f = open( 'catcache.py', 'wb' )
categories = get_categories_from_db()
f.write('x = ' + repr(categories))
f.close()
print '(SET CACHE IN %f)' % (time.time() - start)
import catcache
return catcache.x
这是我简单的pickledfile缓存实现:
def get_categories_from_pickledfile():
path = 'catcache.p'
if not os.path.exists(path):
start = time.time()
pickle.dump( get_categories_from_db(), open( path, 'wb' ) )
print '(SET CACHE IN %f)' % (time.time() - start)
return pickle.load(open( path, 'rb' ));
完整来源:
https://github.com/fsw/pythonCachesBenchmark/blob/master/test.py
我稍后会在此基准测试中添加“Django的低级缓存API”,以了解它们的用途。
因为我的直觉建议在python .py文件中缓存字典是我能得到的最快的方式(比cPickle +文件快30倍)
如上所述,我是Python的新手,所以我可能在这里遗漏了一些东西?
如果没有:为什么这个解决方案不被广泛使用?
答案 0 :(得分:1)
Python有几个可以在这里工作的解决方案:
simplejson
)解决方案,一般情况pickle
非常快(如果您需要更快的速度,请使用cPickle
),而在Python中,您不需要var_export()
之类的任何内容(尽管您可以使用repr()
如果变量具有有效的文字,如果它们是原始类型之一)。 Python中的pickle
更类似于PHP中的serialize
。
你的问题不是很具体,但上面的内容应该会给你一些见解。此外,您需要考虑到PHP和Python有不同的哲学,因此对相同问题的解决方案可能看起来不同。在此特定情况下,pickle
模块应解决您的问题。
答案 1 :(得分:1)
还有另外一种方法。您可以使用某些 ASYNC服务器(如gevent )并在某些全局命名空间中使用活动对象 我不知道你对这样的工作流程有多熟悉,它不同于apache / php“每个请求开始裸露”。
基本上,您加载应用程序,并使用它来处理请求。如果没有请求,它一直存在并且正在睡觉。从数据库加载“类别”后,将它们存储在全局变量或某个模块中。
假设您启动WSGI实例并为其命名应用程序。之后,您可以在该应用程序中使用字典并在那里存储缓存。 因此,没有序列化,网络协议,所有数据都可以直接在RAM中使用。
EDIT1:不要经常使用全局变量,这只是极少数情况下可以在global
命名空间中存储内容(在我看来)。