请求与请求期待 - 响应时间不准确?

时间:2015-04-23 16:01:30

标签: python performance python-3.x python-requests

我有Python代码,可运行10个GET请求并测量响应时间:

from datetime import datetime
from requests_futures.sessions import FuturesSession
import requests

class CustomSession(FuturesSession):

    def __init__(self, *args, **kwargs):
        super(CustomSession, self).__init__(*args, **kwargs)
        self.timing = {}
        self.timing = {}

    def request(self, method, url, *args, **kwargs):
        background_callback = kwargs.pop('background_callback', None)
        test_id = kwargs.pop('test_id', None)

        # start counting
        self.timing[test_id] = {}
        self.timing[test_id]['cS'] = datetime.now()

        def time_it(sess, resp):
            # here if you want to time the server stuff only
            self.timing[test_id]['cE'] = datetime.now()
            if background_callback:
                background_callback(sess, resp)
            # here if you want to include any time in the callback

        return super(CustomSession, self).request(method, url, *args,
                                                  background_callback=time_it,
                                                  **kwargs)

# using requests-futures

print('requests-futures:')

session = CustomSession()

futures = []
for i in range(10):

    futures.append(session.get('http://google.com/', test_id=i))
for future in futures:
    try:
        r = future.result()
        #print((session.timing[i]['cE'] - session.timing[i]['cS']))
    except Exception as e:
        print(e)
for i in range(10):
    print((session.timing[i]['cE'] - session.timing[i]['cS']).total_seconds() * 1000)


# using requests

print('requests:')

for i in range(10):

    check_start_timestamp = datetime.utcnow()
    r = requests.get('http://google.com')
    check_end_timestamp = datetime.utcnow()
    cE = int((check_end_timestamp - check_start_timestamp).total_seconds() * 1000)
    print(cE)

请求期货:

112.959
118.627
160.139
174.32
214.399
224.295
267.557
276.582
316.824
327.00800000000004

请求:

99
104
92
110
100
126
140
112
102
107

看来:

  1. requests-futures的响应时间似乎是附加的(时间越来越大)
  2. 使用普通requests运行速度更快。
  3. 这是正常的吗?我错过了会导致差异的事情吗?

1 个答案:

答案 0 :(得分:4)

问题1

请求 - 期货的响应时间似乎是附加的(时间越来越大)

原因是requests_futures在幕后使用线程池。您可以看到这一点,因为时间发生在块中(为了清楚起见添加了分隔符,可以通过max_workers参数更改线程数):

  • 默认池大小为2:

    161.226
    172.41600000000003
    ---
    250.141
    253.18600000000004
    ---
    329.32800000000003
    342.71000000000004
    ---
    408.21200000000005
    420.614
    ---
    487.356
    499.311
    
  • 游泳池大小为4:

    149.781
    154.761
    151.971
    155.385
    ---
    225.458
    230.596
    239.784
    240.386
    ---
    313.801
    314.056
    
  • 图表(蓝色为2,红色为4):

    enter image description here 如您所见,该组的间距大致相同,这应该是一个请求的响应时间。

理论上,将池大小设置为10会为您的测试提供最佳结果,从而得到以下结果:

252.977
168.379
161.689
165.44
169.238
157.929
171.77
154.089
168.283
159.23999999999998

然而,下面的效果会产生更大的影响。

问题2

使用普通请求的速度要快得多。

我无法确定,但是查看第一个请求批次的时间,它只有~15个单位(微秒?)关闭。这可能是由于:

  • 线程切换。由于正常的请求请求发生在与请求者相同的线程中,因此作业会立即开始。对于线程池,仅在OS切换到正确的线程时才启动请求。这将产生时间开销。
  • 轮询。期货可能会使用某种轮询来检查结果,因此也可能存在延迟。

期货的优点是10个请求的总时间较短,而不是个别时间,所以这个微小的差异并不是真正的问题。