You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Clojure图二分评分代码以提升执行效率?

图二分评分计算的代码优化建议

当前代码用于统计图二分的跨组边数,通过VisualVM采样发现性能瓶颈集中在clojure.core$empty_QMARK_和clojure.core$contains_QMARK_,以下是针对性优化建议:

1. 用reduce替代手动递归遍历,消除empty?的频繁调用

原代码通过递归手动遍历edges,每次递归都要调用empty?检查剩余序列,这会带来额外的性能开销。改用reduce可以自动处理序列遍历,无需手动判断序列是否为空,同时代码更简洁:

(defn tstBisectScore
  "number of edges crossing bisect"
  [bisect edges]
  (reduce (fn [count [n1 n2]]
            (let [in-b1? (contains? bisect n1)
                  in-b2? (contains? bisect n2)]
              (if (not= in-b1? in-b2?)
                (inc count)
                count)))
          0
          edges))

2. 优化bisect的集合类型,提升contains?的查询效率

contains?的性能完全依赖bisect的集合类型:

  • 如果bisect是普通列表或向量,contains?会做线性扫描,速度极慢,必须转换成哈希集合(用(set bisect)或(hash-set ...)生成),哈希集合的contains?是O(1)复杂度。
  • 如果节点是连续的非负整数,推荐使用bit-set,它的contains?操作是位运算,比哈希集合更快:
    ;; 将bisect转换为bit-set
    (def bisect-bit (apply bit-set bisect))
    ;; 之后用(contains? bisect-bit n)查询
    

3. 简化条件判断逻辑,减少布尔运算开销

原代码的复合布尔判断可以简化为直接比较两个节点是否在同一组,等价逻辑更简洁且减少运算步骤:
原条件:

(or (and inb1 inb2)
    (and (not inb1) (not inb2)))

简化后等价逻辑:

(= inb1 inb2)

当该条件为false时,说明边跨组,需要计数。

4. 预转换edges为非惰性序列(如果适用)

如果edges是惰性序列,遍历过程中会有额外的惰性求值开销,可以提前将其转换为向量((vec edges)),提升遍历效率。

内容的提问来源于stack exchange,提问作者rikb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:10:21