1# -*- coding: utf-8 -*- 2# 3# timetest.py 4# 5# Copyright (C) 2010 Andrew Resch <andrewresch@gmail.com> 6# 7# rencode is free software. 8# 9# You may redistribute it and/or modify it under the terms of the 10# GNU General Public License, as published by the Free Software 11# Foundation; either version 3 of the License, or (at your option) 12# any later version. 13# 14# rencode is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17# See the GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with rencode. If not, write to: 21# The Free Software Foundation, Inc., 22# 51 Franklin Street, Fifth Floor 23# Boston, MA 02110-1301, USA. 24# 25 26from rencode import _rencode as rencode 27from rencode import rencode_orig 28 29import sys 30# Hack to deal with python 2 and 3 differences with unicode literals. 31if sys.version < '3': 32 import codecs 33 def u(x): 34 return codecs.unicode_escape_decode(x)[0] 35else: 36 unicode = str 37 def u(x): 38 return x 39 40# Encode functions 41 42def test_encode_fixed_pos_int(): 43 rencode.dumps(40) 44 45def test_encode_fixed_pos_int_orig(): 46 rencode_orig.dumps(40) 47 48def test_encode_fixed_neg_int(): 49 rencode.dumps(-29) 50 51def test_encode_fixed_neg_int_orig(): 52 rencode_orig.dumps(-29) 53 54def test_encode_int_char_size(): 55 rencode.dumps(100) 56 rencode.dumps(-100) 57 58def test_encode_int_char_size_orig(): 59 rencode_orig.dumps(100) 60 rencode_orig.dumps(-100) 61 62def test_encode_int_short_size(): 63 rencode.dumps(27123) 64 rencode.dumps(-27123) 65 66def test_encode_int_short_size_orig(): 67 rencode_orig.dumps(27123) 68 rencode_orig.dumps(-27123) 69 70def test_encode_int_int_size(): 71 rencode.dumps(7483648) 72 rencode.dumps(-7483648) 73 74def test_encode_int_int_size_orig(): 75 rencode_orig.dumps(7483648) 76 rencode_orig.dumps(-7483648) 77 78def test_encode_int_long_long_size(): 79 rencode.dumps(8223372036854775808) 80 rencode.dumps(-8223372036854775808) 81 82def test_encode_int_long_long_size_orig(): 83 rencode_orig.dumps(8223372036854775808) 84 rencode_orig.dumps(-8223372036854775808) 85 86bn = int("9"*62) 87def test_encode_int_big_number(): 88 rencode.dumps(bn) 89 90def test_encode_int_big_number_orig(): 91 rencode_orig.dumps(bn) 92 93def test_encode_float_32bit(): 94 rencode.dumps(1234.56) 95 96def test_encode_float_32bit_orig(): 97 rencode_orig.dumps(1234.56) 98 99def test_encode_float_64bit(): 100 rencode.dumps(1234.56, 64) 101 102def test_encode_float_64bit_orig(): 103 rencode_orig.dumps(1234.56, 64) 104 105def test_encode_fixed_str(): 106 rencode.dumps(b"foobarbaz") 107 108def test_encode_fixed_str_orig(): 109 rencode_orig.dumps(b"foobarbaz") 110 111s = b"f"*255 112def test_encode_str(): 113 rencode.dumps(s) 114 115def test_encode_str_orig(): 116 rencode_orig.dumps(s) 117 118def test_encode_none(): 119 rencode.dumps(None) 120 121def test_encode_none_orig(): 122 rencode_orig.dumps(None) 123 124def test_encode_bool(): 125 rencode.dumps(True) 126 127def test_encode_bool_orig(): 128 rencode_orig.dumps(True) 129 130l = [None, None, None, None] 131def test_encode_fixed_list(): 132 rencode.dumps(l) 133 134def test_encode_fixed_list_orig(): 135 rencode_orig.dumps(l) 136 137ll = [None]*80 138def test_encode_list(): 139 rencode.dumps(ll) 140 141def test_encode_list_orig(): 142 rencode_orig.dumps(ll) 143 144keys = b"abcdefghijk" 145d = dict(zip(keys, [None]*len(keys))) 146 147def test_encode_fixed_dict(): 148 rencode.dumps(d) 149 150def test_encode_fixed_dict_orig(): 151 rencode_orig.dumps(d) 152 153keys2 = b"abcdefghijklmnopqrstuvwxyz1234567890" 154d2 = dict(zip(keys2, [None]*len(keys2))) 155 156def test_encode_dict(): 157 rencode.dumps(d2) 158 159def test_encode_dict_orig(): 160 rencode_orig.dumps(d2) 161 162 163# Decode functions 164 165def test_decode_fixed_pos_int(): 166 rencode.loads(b'(') 167 168def test_decode_fixed_pos_int_orig(): 169 rencode_orig.loads(b'(') 170 171def test_decode_fixed_neg_int(): 172 rencode.loads(b'b') 173 174def test_decode_fixed_neg_int_orig(): 175 rencode_orig.loads(b'b') 176 177def test_decode_int_char_size(): 178 rencode.loads(b'>d') 179 rencode.loads(b'>\x9c') 180 181def test_decode_int_char_size_orig(): 182 rencode_orig.loads(b'>d') 183 rencode_orig.loads(b'>\x9c') 184 185def test_decode_int_short_size(): 186 rencode.loads(b'?i\xf3') 187 rencode.loads(b'?\x96\r') 188 189def test_decode_int_short_size_orig(): 190 rencode_orig.loads(b'?i\xf3') 191 rencode_orig.loads(b'?\x96\r') 192 193def test_decode_int_int_size(): 194 rencode.loads(b'@\x00r1\x00') 195 rencode.loads(b'@\xff\x8d\xcf\x00') 196 197def test_decode_int_int_size_orig(): 198 rencode_orig.loads(b'@\x00r1\x00') 199 rencode_orig.loads(b'@\xff\x8d\xcf\x00') 200 201def test_decode_int_long_long_size(): 202 rencode.loads(b'Ar\x1fILX\x9c\x00\x00') 203 rencode.loads(b'A\x8d\xe0\xb6\xb3\xa7d\x00\x00') 204 205def test_decode_int_long_long_size_orig(): 206 rencode_orig.loads(b'Ar\x1fILX\x9c\x00\x00') 207 rencode_orig.loads(b'A\x8d\xe0\xb6\xb3\xa7d\x00\x00') 208 209def test_decode_int_big_number(): 210 rencode.loads(b'=99999999999999999999999999999999999999999999999999999999999999\x7f') 211 212def test_decode_int_big_number_orig(): 213 rencode_orig.loads(b'=99999999999999999999999999999999999999999999999999999999999999\x7f') 214 215def test_decode_float_32bit(): 216 rencode.loads(b'BD\x9aQ\xec') 217 218def test_decode_float_32bit_orig(): 219 rencode_orig.loads(b'BD\x9aQ\xec') 220 221def test_decode_float_64bit(): 222 rencode.loads(b',@\x93J=p\xa3\xd7\n') 223 224def test_decode_float_64bit_orig(): 225 rencode_orig.loads(b',@\x93J=p\xa3\xd7\n') 226 227def test_decode_fixed_str(): 228 rencode.loads(b'\x89foobarbaz') 229 230def test_decode_fixed_str_orig(): 231 rencode_orig.loads(b'\x89foobarbaz') 232 233def test_decode_str(): 234 rencode.loads(b'255:fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') 235 236def test_decode_str_orig(): 237 rencode_orig.loads(b'255:fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') 238 239def test_decode_none(): 240 rencode.loads(b'E') 241 242def test_decode_none_orig(): 243 rencode_orig.loads(b'E') 244 245def test_decode_bool(): 246 rencode.loads(b'C') 247 248def test_decode_bool_orig(): 249 rencode_orig.loads(b'C') 250 251def test_decode_fixed_list(): 252 rencode.loads(b'\xc4EEEE') 253 254def test_decode_fixed_list_orig(): 255 rencode_orig.loads(b'\xc4EEEE') 256 257def test_decode_list(): 258 rencode.loads(b';EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\x7f') 259 260def test_decode_list_orig(): 261 rencode_orig.loads(b';EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\x7f') 262 263def test_decode_fixed_dict(): 264 rencode.loads(b'q\x81aE\x81cE\x81bE\x81eE\x81dE\x81gE\x81fE\x81iE\x81hE\x81kE\x81jE') 265 266def test_decode_fixed_dict_orig(): 267 rencode_orig.loads(b'q\x81aE\x81cE\x81bE\x81eE\x81dE\x81gE\x81fE\x81iE\x81hE\x81kE\x81jE') 268 269def test_decode_dict(): 270 rencode.loads(b'<\x811E\x810E\x813E\x812E\x815E\x814E\x817E\x816E\x819E\x818E\x81aE\x81cE\x81bE\x81eE\x81dE\x81gE\x81fE\x81iE\x81hE\x81kE\x81jE\x81mE\x81lE\x81oE\x81nE\x81qE\x81pE\x81sE\x81rE\x81uE\x81tE\x81wE\x81vE\x81yE\x81xE\x81zE\x7f') 271 272def test_decode_dict_orig(): 273 rencode_orig.loads(b'<\x811E\x810E\x813E\x812E\x815E\x814E\x817E\x816E\x819E\x818E\x81aE\x81cE\x81bE\x81eE\x81dE\x81gE\x81fE\x81iE\x81hE\x81kE\x81jE\x81mE\x81lE\x81oE\x81nE\x81qE\x81pE\x81sE\x81rE\x81uE\x81tE\x81wE\x81vE\x81yE\x81xE\x81zE\x7f') 274 275 276overall = [ 277 b"5ce750f0954ce1537676c7a5fe38b0de30ba7eb65ce750f0954ce1537676c7a5fe38b0de30ba7eb6", 278 b"fixedlength", 279 u("unicodestring"), 280 u("5ce750f0954ce1537676c7a5fe38b0de30ba7eb65ce750f0954ce1537676c7a5fe38b0de30ba7eb6"), 281 -10, 282 10, 283 120, 284 15600, 285 -15600, 286 7483648, 287 -7483648, 288 8223372036854775808, 289 -8223372036854775808, 290 int("9"*62), 291 1227688834.643409, 292 None, 293 True 294] 295 296def test_overall_encode(): 297 rencode.dumps(overall) 298 299def test_overall_encode_orig(): 300 rencode_orig.dumps(overall) 301 302overall_decode_str = rencode_orig.dumps(overall) 303 304def test_overall_decode(): 305 rencode.loads(overall_decode_str) 306 307def test_overall_decode_orig(): 308 rencode_orig.loads(overall_decode_str) 309 310 311if __name__ == "__main__": 312 import timeit 313 314 iterations = 10000 315 # ANSI escape codes 316 CSI="\x1B[" 317 reset=CSI+"m" 318 319 def do_test(func): 320 print("%s:" % func) 321 new_time = timeit.Timer("%s()" % func, "from __main__ import %s" % func).timeit(iterations) 322 orig_time = timeit.Timer("%s_orig()" % func, "from __main__ import %s_orig" % func).timeit(iterations) 323 if new_time > orig_time: 324 new = CSI + "31m%.3fs%s" % (new_time, reset) 325 orig = CSI + "32m%.3fs%s (%s34m+%.3fs%s) %.2f%%" % (orig_time, reset, CSI, new_time-orig_time, reset, (new_time/orig_time)*100) 326 else: 327 new = CSI + "32m%.3fs%s (%s34m+%.3fs%s) %.2f%%" % (new_time, reset, CSI, orig_time-new_time, reset, (orig_time/new_time)*100) 328 orig = CSI + "31m%.3fs%s" % (orig_time, reset) 329 330 print("\trencode.pyx: %s" % new) 331 print("\trencode.py: %s" % orig) 332 print("") 333 return (new_time, orig_time) 334 335 if len(sys.argv) == 1: 336 loc = list(locals().keys()) 337 338 for t in ("encode", "decode", "overall"): 339 print("*" * 79) 340 print("%s functions:" % (t.title())) 341 print("*" * 79) 342 print("") 343 344 total_new = 0.0 345 total_orig = 0.0 346 for func in loc: 347 if func.startswith("test_%s" % t) and not func.endswith("_orig"): 348 n, o = do_test(func) 349 total_new += n 350 total_orig += o 351 352 print("%s functions totals:" % (t.title())) 353 if total_new > total_orig: 354 new = CSI + "31m%.3fs%s" % (total_new, reset) 355 orig = "%s32m%.3fs%s (%s34m+%.3fs%s) %.2f%%" % (CSI, total_orig, reset, CSI, total_new-total_orig, reset, (total_new/total_orig)*100) 356 else: 357 new = "%s32m%.3fs%s (%s34m+%.3fs%s) %.2f%%" % (CSI, total_new, reset, CSI, total_orig-total_new, reset, (total_orig/total_new)*100) 358 orig = CSI + "31m%.3fs%s" % (total_orig, reset) 359 360 print("\trencode.pyx: %s" % new) 361 print("\trencode.py: %s" % orig) 362 print("") 363 else: 364 for f in sys.argv[1:]: 365 do_test(f) 366