Z3 forJavaに関するパフォーマンスの問題

Yu Feng

Z3 for Javaを使用した現在のプロジェクトで、いくつかのパフォーマンスの問題が発生しています。基本的に、現在の制約のほとんどは非常に単純です。例: (f(x) = 2 && f(y) <= 3) || f(x) <=5

  1. プロジェクト全体で共有される静的コンテキストとソルバーインスタンスを使用しています。

    public class ConstraintManager {
        static Context ctx;
        static Solver solver;
        ...
    }
    

ctxの同じインスタンスで数十億回exprを生成した場合、それは問題になりますか?呼び出すのに最適な時期はいつctx.Dispose()ですか、またはctxを管理するための最良の方法は何ですか?

  1. 次のexpr.Simplify()ようないくつかの制約を単純化するために呼び出しましたf(x)=3 && f(x)<=2しかし、このAPIは非常に遅いことが判明しました。特に制約の長さが増加しました。これは既知の問題ですか、それとも間違って使用したためですか?

  2. を使用しexpr.substitute(expr1, expr2)ていますが、z3が置換後にexprをlet-binding形式に変換することに気付きました。これは数式をよりコンパクトにするためですか?

ニコライ・ビョルナー
  1. Simplifyは、単純な代数的単純化を実行します。場合によっては、その動作を制御できます。たとえば、*は+に分散しますが、これにより実際のオーバーヘッドが発生する可能性があり、この種の単純化をオフにすることができます。コマンドラインからz3-pm:simplifyを使用して、パラメーターを検査します。(一方、Z3は、この単純化が高すぎる場合、式を解くことができない可能性があります)。
  2. 「let-bindings」はプリンターによって提供されます。内部的には、用語はノードが共有される有向非巡回グラフとして表されます。DAGをツリーとして印刷すると、非常にコストがかかる可能性があります(最悪の場合は指数関数的)。そのため、プリンタは、これにより印刷長が短くなると判断したときに、let式を導入します。

.NETおよびJavaAPIは、ガベージコレクターを使用して用語の有効期間を管理します。それらはGCの裁量でリサイクルされます。最高のパフォーマンスを得るには、参照カウントを自分で管理できますが、サポートされているAPIをバイパスする必要があります。リリースされたソースコードには、これに関連するJNI / pinvokeが含まれています。独自の低レベルAPIをローリングするのは大変な作業であり、低レベルの参照カウントもサポートされているAPIほど簡単にプログラミングできないことに注意してください。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事