Python 以下哪一项是最有效的? 问题:
哪一个是最快的 我正在使用lighttpd的Python 以下哪一项是最有效的? 问题:,python,mod-wsgi,fastcgi,lighttpd,wsgi,Python,Mod Wsgi,Fastcgi,Lighttpd,Wsgi,哪一个是最快的 我正在使用lighttpd的mod_fastcgi、python2.7和flup.server.fcgi.WSGIServer 我应该直接在一些输出函数中产生字符串,然后从应用程序返回吗 def app(env, start): start('200 OK', [('Content-Type', 'text/html')]) return some_output_function() def some_output_function(): yield f
mod_fastcgi
、python2.7和flup.server.fcgi.WSGIServer
我应该直接在一些输出函数中产生字符串,然后从应用程序返回吗
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
yield function_that_returns_a_string()
yield 'yada yada'
yield another_function_that_returns_a_string()
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return out
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
yield ''.join(out)
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
yield some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return ''.join(out)
WSGIServer(app).run()
我是否应该从某些输出功能返回数组,然后从应用程序返回
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
yield function_that_returns_a_string()
yield 'yada yada'
yield another_function_that_returns_a_string()
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return out
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
yield ''.join(out)
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
yield some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return ''.join(out)
WSGIServer(app).run()
我是否应该在最后一分钟从一些输出函数生成一个连接数组,然后从应用程序
返回
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
yield function_that_returns_a_string()
yield 'yada yada'
yield another_function_that_returns_a_string()
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return out
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
yield ''.join(out)
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
yield some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return ''.join(out)
WSGIServer(app).run()
我是否应该从一些输出函数中返回最后一分钟加入的数组,然后从应用程序中退出
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
yield function_that_returns_a_string()
yield 'yada yada'
yield another_function_that_returns_a_string()
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return out
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
return some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
yield ''.join(out)
WSGIServer(app).run()
def app(env, start):
start('200 OK', [('Content-Type', 'text/html')])
yield some_output_function()
def some_output_function():
out = []
out.append(function_that_returns_a_string())
out.append('yada yada')
out.append(another_function_that_returns_a_string())
return ''.join(out)
WSGIServer(app).run()
测试结果
通过创建一个简单的测试应用程序,输出函数有一个函数调用,然后是十六个“yada-yada”字符串,然后是另一个函数调用作为输出,我使用ApacheBench收集了一些令人惊讶的平均请求时间
sudo ab -n10000 -c128 localhost/testapp/
- 44毫秒直接在
某些输出函数
中生成字符串,然后从应用程序返回
- 44毫秒从
某些输出功能
返回数组,然后从应用程序
- 30毫秒从
某些输出功能
生成最后一分钟加入的数组,然后从应用程序返回
- 30毫秒从
某些输出函数
返回最后一分钟加入的数组,然后从应用程序
更有趣的是,将“yada-yada”输出字符串的数量增加八倍,达到128个“yada-yada”输出字符串时,结果如下:
- 146毫秒直接在
某些输出函数
中生成字符串,然后从应用程序返回
- 146毫秒从
某些输出功能
返回数组,然后从应用程序
- 30毫秒从
某些输出功能
生成最后一分钟加入的数组,然后从应用程序返回
- 30毫秒从
某些输出函数
返回最后一分钟加入的数组,然后从应用程序
似乎节省时间的一个常见因素是构建一个字符串数组,然后在退出内部输出函数之前加入它,而不是在任何地方都屈服。无论你是屈服于内部而返回外部,还是屈服于内部而返回内部,都不会改变任何事情
因此,现在唯一的问题是,我应该屈服于内部还是外部?一般来说,在处理大量数据时,规则生成器比列表更有效。如果元素的数量较少(例如,在您的示例中,只有三个元素),则列表的开销将较小
无论您选择哪种方法,从缓存或数据存储中获取数据所花费的时间(几十到几百毫秒)都很可能使它相形见绌。缩短10毫秒的响应时间可能不值得担心
应该使用生成器的原因不是为了速度,而是因为大型响应将流式传输到客户端,这将使用更少的内存并释放服务器来处理更多的请求。这在使用异步服务器(例如带有eventlet workers的gunicorn、Tornado等)时尤其有用
要回答这个问题:
所以现在唯一的问题是,我应该屈服于内部还是外部
实际上,它应该没有任何区别。生成大量小字符串比生成单个大字符串更慢,因为WSGI规范要求底层WSGI服务器/适配器在写入下一个字符串之前对每个字符串执行刷新。字符串的刷新可以通过许多层,这取决于所使用的服务器,最终可以在套接字上刷新。由于您要多次这样做,因此编写一个更大的字符串的成本会更高。这是一个很好的观点,但我的原始测试表明,请求时间似乎随着更多的产生
语句而增加,但在使用列表、加入,然后屈服一次。我真的应该单独使用带有收益率语句的生成器吗?编辑:再想一想,可以合理地说生成器方法在内存上更轻,但速度更慢,列表方法更快,但占用更多内存吗?我认为您在使用yield时会看到时间的增加,因为您生成了大量小字符串。产生1000个小字符串比包含1000个元素的列表的开销更大。请尝试使用生成器返回1MB(或更高)的响应,该生成器将数据拆分为128KB(或更高)的块,而不是包含相同数据的列表。生成器方法允许您更好地调整系统(例如,更高的内存使用率以获得更快的响应)。对于列表,你只有一个选择:将所有内容存储在内存中,然后一次性发送。这很有意义。因此,在较慢的方法中,我最里面的函数中的每个yield
,都可能使小字符串执行一次完整的“外部”行程,而较快的方法不会占用更多字符串的时间,因为它不会被迫对每个字符串执行刷新?