Mercurial > hg
view tests/get-with-headers.py @ 41979:0d467e4de4ae
discovery: fix embarrassing typo in slice definition
The code introduced in e514799e4e07 ended up having a silly bug. The indexing
selected a single item slice picking only p1. The discovery result was still
correct, but the sampling was hampered, sometime leading to much more round
trips being performed.
Fixing this issue restore the previous sampling behavior.
This fix has a negative performance impact on the pathological case the previous
test has been built.
# parent of this changesets
! wall 5.313884 comb 5.310000 user 5.260000 sys 0.050000 (best of 5)
! wall 6.711860 comb 6.710000 user 6.670000 sys 0.040000 (max of 5)
! wall 5.844016 comb 5.842000 user 5.784000 sys 0.058000 (avg of 5)
! wall 5.778635 comb 5.780000 user 5.740000 sys 0.040000 (median of 5)
# With this changesets.
! wall 6.350879 comb 6.350000 user 6.300000 sys 0.050000 (best of 5)
! wall 6.653647 comb 6.660000 user 6.480000 sys 0.180000 (max of 5)
! wall 6.492762 comb 6.494000 user 6.414000 sys 0.080000 (avg of 5)
! wall 6.547577 comb 6.550000 user 6.490000 sys 0.060000 (median of 5)
Changeset e514799e4e07 raised the question of using the "_uncheckedparentrevs"
instead of the current code. So I ran comparative timing:
# old code: 55919b96c02a (e514799e4e07 parent)
! wall 64.078708 comb 64.080000 user 63.160000 sys 0.920000 (best of 5)
! wall 68.296300 comb 68.290000 user 67.410000 sys 0.880000 (max of 5)
! wall 65.899075 comb 65.894000 user 65.082000 sys 0.812000 (avg of 5)
! wall 66.140286 comb 66.130000 user 65.330000 sys 0.800000 (median of 5)
# buggy code: e514799e4e07
! wall 46.605362 comb 46.610000 user 45.880000 sys 0.730000 (best of 5)
! wall 48.619659 comb 48.620000 user 47.890000 sys 0.730000 (max of 5)
! wall 47.350247 comb 47.350000 user 46.672000 sys 0.678000 (avg of 5)
! wall 46.983224 comb 46.980000 user 46.350000 sys 0.630000 (median of 5)
# fixed code: e514799e4e07 with this fix
! wall 55.858460 comb 55.850000 user 55.090000 sys 0.760000 (best of 5)
! wall 59.048805 comb 59.060000 user 58.110000 sys 0.950000 (max of 5)
! wall 57.192639 comb 57.192000 user 56.350000 sys 0.842000 (avg of 5)
! wall 57.056373 comb 57.060000 user 56.160000 sys 0.900000 (median of 5)
# version using uncheckedparents
! wall 56.471916 comb 56.470000 user 55.630000 sys 0.840000 (best of 5)
! wall 58.228793 comb 58.230000 user 57.600000 sys 0.630000 (max of 5)
! wall 57.377583 comb 57.378000 user 56.674000 sys 0.704000 (avg of 5)
! wall 57.008843 comb 57.010000 user 56.330000 sys 0.680000 (median of 5)
So it looks like the overhead from `_uncheckedparentrevs` is not that impactful.
I'll investigate this shortly. I'm almost done updating our benchmark suite
with more meaningful discovery cases.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 14 Mar 2019 19:13:45 +0000 |
parents | fe11fc7e541f |
children | 2372284d9457 |
line wrap: on
line source
#!/usr/bin/env python """This does HTTP GET requests given a host:port and path and returns a subset of the headers plus the body of the result.""" from __future__ import absolute_import import argparse import json import os import sys from mercurial import ( pycompat, util, ) httplib = util.httplib try: import msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) except ImportError: pass stdout = getattr(sys.stdout, 'buffer', sys.stdout) parser = argparse.ArgumentParser() parser.add_argument('--twice', action='store_true') parser.add_argument('--headeronly', action='store_true') parser.add_argument('--json', action='store_true') parser.add_argument('--hgproto') parser.add_argument('--requestheader', nargs='*', default=[], help='Send an additional HTTP request header. Argument ' 'value is <header>=<value>') parser.add_argument('--bodyfile', help='Write HTTP response body to a file') parser.add_argument('host') parser.add_argument('path') parser.add_argument('show', nargs='*') args = parser.parse_args() twice = args.twice headeronly = args.headeronly formatjson = args.json hgproto = args.hgproto requestheaders = args.requestheader tag = None def request(host, path, show): assert not path.startswith('/'), path global tag headers = {} if tag: headers['If-None-Match'] = tag if hgproto: headers['X-HgProto-1'] = hgproto for header in requestheaders: key, value = header.split('=', 1) headers[key] = value conn = httplib.HTTPConnection(host) conn.request("GET", '/' + path, None, headers) response = conn.getresponse() stdout.write(b'%d %s\n' % (response.status, response.reason.encode('ascii'))) if show[:1] == ['-']: show = sorted(h for h, v in response.getheaders() if h.lower() not in show) for h in [h.lower() for h in show]: if response.getheader(h, None) is not None: stdout.write(b"%s: %s\n" % (h.encode('ascii'), response.getheader(h).encode('ascii'))) if not headeronly: stdout.write(b'\n') data = response.read() if args.bodyfile: bodyfh = open(args.bodyfile, 'wb') else: bodyfh = stdout # Pretty print JSON. This also has the beneficial side-effect # of verifying emitted JSON is well-formed. if formatjson: # json.dumps() will print trailing newlines. Eliminate them # to make tests easier to write. data = json.loads(data) lines = json.dumps(data, sort_keys=True, indent=2).splitlines() for line in lines: bodyfh.write(pycompat.sysbytes(line.rstrip())) bodyfh.write(b'\n') else: bodyfh.write(data) if args.bodyfile: bodyfh.close() if twice and response.getheader('ETag', None): tag = response.getheader('ETag') return response.status status = request(args.host, args.path, args.show) if twice: status = request(args.host, args.path, args.show) if 200 <= status <= 305: sys.exit(0) sys.exit(1)