Skip to content

zen-engine python 0.37.1 and 0.38.4 perfromace issue #441

@RYefccd

Description

@RYefccd

when I run zen-engine code and decide which object to cache for performance. I notice that version of
zen-engine==0.37.1 and zen-engine==0.38.4 in python pypi
has diffrent excuting time.

zen-engine==0.37.1run faster nearly 30 times to zen-engine>=0.38.4

test code is below:

(zen-rule) ryefccd@republic:~/workspace/zen-rule$ uv pip install zen-engine==0.37.1
⠸ zen-engine==0.37.1                                                                                                               
Resolved 1 package in 506ms
Uninstalled 1 package in 1ms
Installed 1 package in 7ms
 - zen-engine==0.24.2
 + zen-engine==0.37.1
(zen-rule) ryefccd@republic:~/workspace/zen-rule$ python zen_engine_perf_test.py bench
Namespace(name='bench')
demo1: 0.11221965699223801 s/10000ops
demo2: 0.07348775095306337 s/10000ops
demo3: 0.026231597003061324 s/10000ops
(zen-rule) ryefccd@republic:~/workspace/zen-rule$ uv pip install zen-engine==0.38.4
Resolved 1 package in 317ms
Uninstalled 1 package in 0.57ms
Installed 1 package in 7ms
 - zen-engine==0.37.1
 + zen-engine==0.38.4
(zen-rule) ryefccd@republic:~/workspace/zen-rule$ python zen_engine_perf_test.py bench
Namespace(name='bench')
demo1: 2.993424592015799 s/10000ops
demo2: 2.8703583830501884 s/10000ops
demo3: 2.9108538199798204 s/10000ops
import timeit
import argparse
import zen
from zen import ZenEngine, ZenDecision
graph_content = """
{
  "contentType": "application/vnd.gorules.decision",
  "nodes": [
    {
      "type": "inputNode",
      "content": {
        "schema": ""
      },
      "id": "d4c5fdef-96c0-4c5e-8e7b-e1e4f9797251",
      "name": "request",
      "position": {
        "x": 245,
        "y": 355
      }
    },
    {
      "type": "outputNode",
      "content": {
        "schema": ""
      },
      "id": "a2cb6433-140b-4d2c-89f2-0e4f3140dd1a",
      "name": "response",
      "position": {
        "x": 1120,
        "y": 365
      }
    },
    {
      "type": "expressionNode",
      "content": {
        "expressions": [
          {
            "id": "8bf2c094-3115-4608-9416-1c854c68cc89",
            "key": "result",
            "value": "num * 2"
          }
        ],
        "passThrough": false,
        "inputField": null,
        "outputPath": null,
        "executionMode": "single"
      },
      "id": "45bbd693-493b-415d-8ad6-0d57c9a40d3e",
      "name": "expression1",
      "position": {
        "x": 715,
        "y": 400
      }
    }
  ],
  "edges": [
    {
      "id": "84fa9a9a-e90a-4322-be6f-94d3efd84edf",
      "sourceId": "d4c5fdef-96c0-4c5e-8e7b-e1e4f9797251",
      "type": "edge",
      "targetId": "45bbd693-493b-415d-8ad6-0d57c9a40d3e"
    },
    {
      "id": "0cd7ec7d-05d9-4497-abc7-d51b2202ddb4",
      "sourceId": "45bbd693-493b-415d-8ad6-0d57c9a40d3e",
      "type": "edge",
      "targetId": "a2cb6433-140b-4d2c-89f2-0e4f3140dd1a"
    }
  ]
}
"""


def init_zen():
    engine = zen.ZenEngine()
    decision = engine.create_decision(graph_content)
    return graph_content, engine, decision


con, engine, decision = init_zen()


def demo1(con, engine, decision):
    decision = engine.create_decision(con)
    input = {
      "num": 10,
    }
    result = decision.evaluate(input, {"trace": True})
    return result


def demo2(con, engine, decision):
    input = {
      "num": 10,
    }
    result = decision.evaluate(input, {"trace": True})
    return result


def demo3(con, engine, decision):
    input = {
      "num": 10,
    }
    result = decision.evaluate(input, {"trace": False})
    return result


# 1. Create the ArgumentParser object
parser = argparse.ArgumentParser(description="test different zen engine usage demo performace")

# 2. Add arguments
parser.add_argument("name", help="name of test function.", choices=['demo1', 'demo2', 'demo3', 'bench'])

# 3. Parse the arguments
args = parser.parse_args()

# 4. Access and use the arguments
if args.name in globals():
  print(globals()[args.name](con, engine, decision))
else:
  if args.name == 'bench':
    number = 10000
    r1 = timeit.timeit('demo1(con, engine, decision)', number=number, globals=globals())
    print(f"demo1: {r1} s/{number}ops")
    r2 = timeit.timeit('demo2(con, engine, decision)', number=number, globals=globals())
    print(f"demo2: {r2} s/{number}ops")
    r3 = timeit.timeit('demo3(con, engine, decision)', number=number, globals=globals())
    print(f"demo3: {r3} s/{number}ops")
  else:
    print(f"{args.name} function not found")

run cmd:

## run demo1 
python zen_engine_perf_test.py demo1
## run demo2
python zen_engine_perf_test.py demo2
## run demo3
python zen_engine_perf_test.py demo3
##  run demo1,demo2,demo3 benchmark
python zen_engine_perf_test.py bench

system and python info:

$ cpuinfo 
Python Version: 3.10.19.final.0 (64 bit)
Cpuinfo Version: 9.0.0
Vendor ID Raw: GenuineIntel
Hardware Raw: 
Brand Raw: Intel(R) Core(TM) Ultra 7 265K
Hz Advertised Friendly: 2.5898 GHz
Hz Actual Friendly: 2.5898 GHz
Hz Advertised: (2589769000, 0)
Hz Actual: (2589769000, 0)
Arch: X86_64
Bits: 64
Count: 20
Arch String Raw: x86_64
L1 Data Cache Size: 
L1 Instruction Cache Size: 
L2 Cache Size: 
L2 Cache Line Size: 
L2 Cache Associativity: 
L3 Cache Size: 31457280
Stepping: 2
Model: 198
Family: 6
Processor Type: 
Flags: 3dnowprefetch, abm, acpi, adx, aes, aperfmperf, apic, arat, arch_capabilities, arch_lbr, arch_perfmon, art, avx, avx2, avx_vnni, bmi1, bmi2, bts, bus_lock_detect, clflush, clflushopt, clwb, cmov, constant_tsc, cpuid, cpuid_fault, cx16, cx8, de, ds_cpl, dtes64, dtherm, dts, ept, ept_ad, erms, est, f16c, flexpriority, flush_l1d, fma, fpu, fsgsbase, fsrm, fxsr, gfni, hfi, ht, hwp, hwp_act_window, hwp_epp, hwp_notify, hwp_pkg_req, ibpb, ibrs, ibrs_enhanced, ibt, ida, intel_pt, invpcid, lahf_lm, lam, lm, mca, mce, md_clear, mmx, monitor, movbe, movdir64b, movdiri, msr, mtrr, nonstop_tsc, nopl, nx, ospke, pae, pat, pbe, pcid, pclmulqdq, pdcm, pdpe1gb, pebs, pge, pku, pln, pni, popcnt, pse, pse36, pts, rdpid, rdrand, rdseed, rdt_a, rdtscp, rep_good, sdbg, sep, serialize, sha_ni, smap, smep, smx, split_lock_detect, ss, ssbd, sse, sse2, sse4_1, sse4_2, ssse3, stibp, syscall, tm, tm2, tpr_shadow, tsc, tsc_adjust, tsc_deadline_timer, tsc_known_freq, umip, user_shstk, vaes, vme, vmx, vnmi, vpclmulqdq, vpid, waitpkg, wbnoinvd, x2apic, xgetbv1, xsave, xsavec, xsaveopt, xsaves, xtopology, xtpr

$ python -V
Python 3.10.19

this is the code compare: python-v0.37.1...python-v0.38.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions