Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 慢速数据脚本查询_Clojure_Datascript - Fatal编程技术网

Clojure 慢速数据脚本查询

Clojure 慢速数据脚本查询,clojure,datascript,Clojure,Datascript,我正在使用Datascript查询一个树结构,以查找 到目前为止,我已经得到了两个节点的名称,但是速度非常慢 --你知道为什么(或者有更好的方法)吗 我最初打算用而不是来排除所有比祖先更高的祖先 最后一个常见的,但Datascript当前不支持而不支持,因此这两个 父条款 模式是: :children {:db/valueType :db.type/ref :db/cardinality :db.cardinality/many :db/index

我正在使用Datascript查询一个树结构,以查找 到目前为止,我已经得到了两个节点的名称,但是速度非常慢 --你知道为什么(或者有更好的方法)吗

我最初打算用
而不是
来排除所有比祖先更高的祖先
最后一个常见的,但Datascript当前不支持
而不支持
,因此这两个
父条款

模式是:

:children {:db/valueType :db.type/ref 
           :db/cardinality :db.cardinality/many 
           :db/index true}
:name {:db/index true}

嗯,递归规则不是DataScript中最快的东西。因此,您可以通过将
parent
规则直接内联到查询代码中,使查询速度加快一点

另一件事是,查询并不是最快的,DataScript也是如此。解析查询、分配中间集合、对它们进行迭代、管理变量等花费了相当多的时间。与手动访问数据库/索引相比,有两种情况下您更喜欢查询:

  • 查询的工作速度比您自己编写的快(例如,在处理大型关系时,查询将使用哈希联接,手动编写这种联接非常繁琐)
  • 查询以比命令式算法简单得多的方式表达您的问题
  • 在你的例子中,这两个都不是真的(你不是真的在处理关系,你是在线性地处理图表)。此外,还有一个bug:如果node1和node2具有公共的直接父节点,则查询将无法工作

    我建议通过直接访问实体来做同样的事情。实体只是索引查找,没有任何与查询相关的开销,因此在这种简单的情况下,它们应该工作得更快

    这样的东西应该足够了:

    (defn parent [node]
      (first (:_children node)))
    
    
    (defn ancestors [node]
      (->> node
           (iterate parent)
           (take-while some?)
           reverse))
    
    
    (defn last-common-ancestor [db name1 name2]
      (let [node1 (d/entity db [:name name1])
            node2 (d/entity db [:name name2])]
             ;; zipping ancestor chains together
        (->> (map vector (ancestors node1) (ancestors node2))
             ;; selecting common prefix
             (take-while (fn [[ac1 ac2]] (= ac1 ac2)))
             ;; last item in common prefix is what you looking for
             (last))))
    
    (defn parent [node]
      (first (:_children node)))
    
    
    (defn ancestors [node]
      (->> node
           (iterate parent)
           (take-while some?)
           reverse))
    
    
    (defn last-common-ancestor [db name1 name2]
      (let [node1 (d/entity db [:name name1])
            node2 (d/entity db [:name name2])]
             ;; zipping ancestor chains together
        (->> (map vector (ancestors node1) (ancestors node2))
             ;; selecting common prefix
             (take-while (fn [[ac1 ac2]] (= ac1 ac2)))
             ;; last item in common prefix is what you looking for
             (last))))