1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#!/usr/bin/env python3
# Copyright 2017 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import json
import os
import sys
import time
import json5
ALL_BENCHMARKS = (
'64KB-min.json',
'bitly-usa-gov.json',
'twitter.json',
)
DEFAULT_ITERATIONS = 3
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--pure', action='store_true')
parser.add_argument(
'-n', '--num-iterations', default=DEFAULT_ITERATIONS, type=int
)
parser.add_argument('benchmarks', nargs='*')
args = parser.parse_args()
if not args.benchmarks:
args.benchmarks = [os.path.join(THIS_DIR, d) for d in ALL_BENCHMARKS]
file_contents = []
for f in args.benchmarks:
with open(f, encoding='utf-8') as fp:
file_contents.append(fp.read())
# json.decoder.c_scanstring = py_scanstring
def py_maker(*args, **kwargs):
del args
del kwargs
decoder = json.JSONDecoder()
decoder.scan_once = json.scanner.py_make_scanner(decoder)
decoder.parse_string = json.decoder.py_scanstring
json.decoder.scanstring = decoder.parse_string
return decoder
maker = py_maker if args.pure else json.JSONDecoder
all_times = []
for i, c in enumerate(file_contents):
json_time = 0.0
json5_time = 0.0
for _ in range(args.num_iterations):
start = time.time()
json_obj = json.loads(c, cls=maker)
mid = time.time()
json5_obj = json5.loads(c)
end = time.time()
json_time += mid - start
json5_time += end - mid
assert json5_obj == json_obj
all_times.append((json_time, json5_time))
for i, (json_time, json5_time) in enumerate(all_times):
fname = os.path.basename(args.benchmarks[i])
if json5_time and json_time:
if json5_time > json_time:
avg = json5_time / json_time
print(
f'{fname:-%20s}: JSON was {avg:5.1f}x faster '
f'({json_time:.6f} to {json5_time:.6fs}'
)
else:
avg = json_time / json5_time
print(
f'{fname:-%20s}: JSON5 was {avg:5.1f}x faster '
f'({json5_time:.6f} to {json_time:.6fs}'
)
elif json5_time:
print(
f'{fname:-20s}: JSON5 took {json5_time:.6f} secs, '
f'JSON was too fast to measure'
)
elif json_time:
print(
f'{fname:-20s}: JSON took {json_time:.6f} secs, '
f'JSON5 was too fast to measure'
)
else:
print(f'{fname:-20s}: both were too fast to measure')
return 0
if __name__ == '__main__':
sys.exit(main())
|