Solving a large number of very simple queries with minimal latency #5577
jonathan-laurent
started this conversation in
General
Replies: 2 comments
-
I simplify your question: import z3
import timeit
x = z3.Bool('x')
BENCH_SIZE = 1000
def sat_reset(make_solver):
solver = make_solver()
for _ in range(BENCH_SIZE):
solver.reset()
solver.add(x)
def sat_push_pop(make_solver):
solver = make_solver()
for _ in range(BENCH_SIZE):
solver.push()
solver.add(x)
solver.pop()
def benchmark_method(f, label):
t = timeit.Timer(f).timeit(1) / BENCH_SIZE
print(f"{label:20s} {t*1e6:4.0f}us")
benchmark_method(lambda: sat_reset(z3.Solver), "Solver")
benchmark_method(lambda: sat_push_pop(z3.Solver), "Incremental1")
benchmark_method(lambda: sat_reset(z3.SimpleSolver), "SimpleSolver")
benchmark_method(lambda: sat_push_pop(z3.SimpleSolver), "Incremental2") Result:
It looks like the problem isn't with the Solver, but with the |
Beta Was this translation helpful? Give feedback.
0 replies
-
It seems that the problem is with OCaml benchmark: open Z3
open Z3.Arithmetic
let is_unsat = function
| Solver.UNSATISFIABLE -> true
| _ -> false
let bench () =
let ctx = mk_context [("model", "false"); ("proof", "false")] in
let real = Real.mk_sort ctx in
let x = Expr.mk_const ctx (Symbol.mk_string ctx "x") real in
let zero = Real.mk_numeral_i ctx 0 in
let one = Real.mk_numeral_i ctx 1 in
let fml = Boolean.mk_implies ctx (mk_gt ctx x one) (mk_gt ctx x zero) in
let fml_neg = Boolean.mk_not ctx fml in
let solver = Solver.mk_simple_solver ctx in
let check () = begin
assert (Solver.get_num_assertions solver = 0);
assert (is_unsat (Solver.check solver [fml_neg]));
end in
let check_reset () = begin
Solver.add solver [fml_neg];
assert (is_unsat (Solver.check solver []));
Solver.reset solver;
end in
let check_push_pop () = begin
Solver.push solver;
Solver.add solver [fml_neg];
assert (is_unsat (Solver.check solver []));
Solver.pop solver 1;
end in
let open Core_bench in
let benchs = [
Bench.Test.create ~name:"Check" check;
Bench.Test.create ~name:"Reset" check_reset;
Bench.Test.create ~name:"Push-pop" check_push_pop
] in
benchs |> Bench.make_command |> Core.Command.run
let () = bench () Output:
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I am using Z3 on a workload where I have to solve a large number of very simple SAT queries (only a handful of clauses) as fast as possible. To figure out the best way to do it using the Z3 API, I generated a simple benchmark of queries such as:
Then, I compared several uses of the Z3 API:
Results:
Full benchmark code
My questions:
push
andpop
to implement a resetting behavior. Do you have any idea why this is the case?Also, given the large discrepancy between
Solver
andSimpleSolver
on this benchmark, I am wondering whether more discussion about this should be warranted in the documentation / tutorials.Beta Was this translation helpful? Give feedback.
All reactions