如何提升读取大文件并返回下载的Python CGI性能?
我有一个用Python写的CGI脚本,它会检查同一个IP地址访问的次数,如果没问题,就会从磁盘上读取一个很大的文件(11MB),然后把这个文件作为下载返回给用户。
这个脚本能工作,但速度很慢。问题似乎出在每次都要重复读取这个大文件上:
def download_demo():
"""
Returns the demo file
"""
file = open(FILENAME, 'r')
buff = file.read()
print "Content-Type:application/x-download\nContent-Disposition:attachment;filename=%s\nContent-Length:%s\n\n%s" % (os.path.split(FILENAME)[-1], len(buff), buff)
我该怎么让这个过程更快呢?我想过用内存盘来存放这个文件,但肯定还有更好的解决办法。使用mod_wsgi
代替CGI脚本会有帮助吗?这样我能把这个大文件放在Apache的内存空间里吗?
任何帮助都非常感谢。
4 个回答
1
试着一次读取和输出大约16KB的数据块。可能是Python在后台做了一些比较慢的操作,手动缓冲可能会更快。
你不需要使用比如说内存磁盘之类的,操作系统的磁盘缓存应该会为你缓存文件内容。
2
你为什么把所有内容都放在一个打印语句里呢?Python在处理这些内容的时候,需要生成几个临时字符串来处理标题。而因为最后的那个%s,Python还得把整个文件的内容存放在两个不同的字符串变量里。这种做法其实可以改进一下。
print "Content-Type:application/x-download\nContent-Disposition:attachment;filename=%s\nContent-Length:%s\n\n" % (os.path.split(FILENAME)[-1], len(buff))
print buff
你也可以考虑使用原始输入输出模块来读取文件,这样Python就不会创建那些你并不需要的临时缓冲区了。
9
使用mod_wsgi,并且用类似下面的方式:
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain')]
start_response(status, response_headers)
file = open('/usr/share/dict/words', 'rb')
return environ['wsgi.file_wrapper'](file)
换句话说,使用WSGI标准中的wsgi.file_wrapper扩展,这样可以让Apache和mod_wsgi更高效地发送文件内容,使用sendfile或mmap。这意味着你的应用程序根本不需要把文件读到内存里。