integration_tests/cpython_benchmark/fury_benchmark.py (175 lines of code) (raw):
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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 array
from dataclasses import dataclass
import datetime
import os
import random
import sys
from typing import Any, Dict, List
import pyfury
import pyperf
# The benchmark case is rewritten from pyperformance bm_pickle
# https://github.com/python/pyperformance/blob/main/pyperformance/data-files/benchmarks/bm_pickle/run_benchmark.py
DICT = {
"ads_flags": 0,
"age": 18,
"birthday": datetime.date(1980, 5, 7),
"bulletin_count": 0,
"comment_count": 0,
"country": "BR",
"encrypted_id": "G9urXXAJwjE",
"favorite_count": 9,
"first_name": "",
"flags": 412317970704,
"friend_count": 0,
"gender": "m",
"gender_for_display": "Male",
"id": 302935349,
"is_custom_profile_icon": 0,
"last_name": "",
"locale_preference": "pt_BR",
"member": 0,
"tags": ["a", "b", "c", "d", "e", "f", "g"],
"profile_foo_id": 827119638,
"secure_encrypted_id": "Z_xxx2dYx3t4YAdnmfgyKw",
"session_number": 2,
"signup_id": "201-19225-223",
"status": "A",
"theme": 1,
"time_created": 1225237014,
"time_updated": 1233134493,
"unread_message_count": 0,
"user_group": "0",
"username": "collinwinter",
"play_count": 9,
"view_count": 7,
"zip": "",
}
LARGE_DICT = {str(i): i for i in range(2**10 + 1)}
TUPLE = (
[
265867233,
265868503,
265252341,
265243910,
265879514,
266219766,
266021701,
265843726,
265592821,
265246784,
265853180,
45526486,
265463699,
265848143,
265863062,
265392591,
265877490,
265823665,
265828884,
265753032,
],
60,
)
LARGE_TUPLE = tuple(range(2**20 + 1))
LARGE_FLOAT_TUPLE = tuple([random.random() * 10000 for _ in range(2**20 + 1)])
LARGE_BOOLEAN_TUPLE = tuple([bool(random.random() > 0.5) for _ in range(2**20 + 1)])
LIST = [[list(range(10)), list(range(10))] for _ in range(10)]
LARGE_LIST = [i for i in range(2**20 + 1)]
def mutate_dict(orig_dict, random_source):
new_dict = dict(orig_dict)
for key, value in new_dict.items():
rand_val = random_source.random() * sys.maxsize
if isinstance(key, (int, bytes, str)):
new_dict[key] = type(key)(rand_val)
return new_dict
random_source = random.Random(5)
DICT_GROUP = [mutate_dict(DICT, random_source) for _ in range(3)]
@dataclass
class ComplexObject1:
f1: Any = None
f2: str = None
f3: List[str] = None
f4: Dict[pyfury.Int8Type, pyfury.Int32Type] = None
f5: pyfury.Int8Type = None
f6: pyfury.Int16Type = None
f7: pyfury.Int32Type = None
f8: pyfury.Int64Type = None
f9: pyfury.Float32Type = None
f10: pyfury.Float64Type = None
f11: pyfury.Int16ArrayType = None
f12: List[pyfury.Int16Type] = None
@dataclass
class ComplexObject2:
f1: Any
f2: Dict[pyfury.Int8Type, pyfury.Int32Type]
COMPLEX_OBJECT = ComplexObject1(
f1=ComplexObject2(f1=True, f2={-1: 2}),
f2="abc",
f3=["abc", "abc"],
f4={1: 2},
f5=2**7 - 1,
f6=2**15 - 1,
f7=2**31 - 1,
f8=2**63 - 1,
f9=1.0 / 2,
f10=1 / 3.0,
f11=array.array("h", [1, 2]),
f12=[-1, 4],
)
def fury_object(language, ref_tracking, obj):
fury = pyfury.Fury(language=language, ref_tracking=ref_tracking)
binary = fury.serialize(obj)
fury.deserialize(binary)
def benchmark_args():
parser = argparse.ArgumentParser(description="Fury Benchmark")
parser.add_argument("--xlang", action="store_true", default=False)
parser.add_argument("--no-ref", action="store_true", default=False)
parser.add_argument("--disable-cython", action="store_true", default=False)
if "--help" in sys.argv:
parser.print_help()
return None
args, unknown_args = parser.parse_known_args()
sys.argv = sys.argv[:1] + unknown_args
return args
def micro_benchmark():
args = benchmark_args()
runner = pyperf.Runner()
if args and args.disable_cython:
os.environ["ENABLE_FURY_CYTHON_SERIALIZATION"] = "0"
sys.argv += ["--inherit-environ", "ENABLE_FURY_CYTHON_SERIALIZATION"]
runner.parse_args()
language = pyfury.Language.XLANG if args.xlang else pyfury.Language.PYTHON
runner.bench_func("fury_dict", fury_object, language, not args.no_ref, DICT)
runner.bench_func(
"fury_large_dict", fury_object, language, not args.no_ref, LARGE_DICT
)
runner.bench_func(
"fury_dict_group", fury_object, language, not args.no_ref, DICT_GROUP
)
runner.bench_func("fury_tuple", fury_object, language, not args.no_ref, TUPLE)
runner.bench_func(
"fury_large_tuple", fury_object, language, not args.no_ref, LARGE_TUPLE
)
runner.bench_func("fury_list", fury_object, language, not args.no_ref, LIST)
runner.bench_func(
"fury_large_float_tuple",
fury_object,
language,
not args.no_ref,
LARGE_FLOAT_TUPLE,
)
runner.bench_func(
"fury_large_boolean_tuple",
fury_object,
language,
not args.no_ref,
LARGE_BOOLEAN_TUPLE,
)
runner.bench_func("fury_list", fury_object, language, not args.no_ref, LIST)
runner.bench_func(
"fury_large_list", fury_object, language, not args.no_ref, LARGE_LIST
)
runner.bench_func(
"fury_complex", fury_object, language, not args.no_ref, COMPLEX_OBJECT
)
if __name__ == "__main__":
micro_benchmark()