Um modo idiossincrático / eficiente de Clojure para interceptar dois vetores ordenados a priori?

Eu tenho um par de vetoresx ey de itens exclusivos, cada um dos quais eu sei ser classificado. Eu gostaria de ter a interseção dos dois, mantendo a ordem de classificação. O resultado ideal seria outro vetor, para acesso aleatório rápido.

A geração abaixo é meramente por exemplo, minhax ey virão pré-definidos e pré-distintos (na verdade são amostras de tempo).

(defn gen-example [c] (-> (repeatedly c #(-> c rand int)) distinct sort vec))

user=> (def x (gen-example 100000)) (count x)
#'user/x
63161
user=> (def y (gen-example 100000)) (count y)
#'user/y
63224

Eu sei que o Clojure temclojure.set/intersection que pode trabalhar em umsorted-set. Minhasx ey possuem as mesmas propriedades (elementos distintos classificados), mas não são do mesmo tipo.

Pergunta 1: Existe uma maneira melhor / mais rápida de converterx ey parasorted-sets do que(apply sorted-set x) dado que eles já são distintos e classificados?

user=> (time (def ssx (apply sorted-set x)))
"Elapsed time: 607.642592 msecs"
user=> (time (def ssy (apply sorted-set y)))
"Elapsed time: 617.046022 msecs"

Agora estou pronto para realizar minha interseção

user=> (time (count (clojure.set/intersection ssx ssy)))
"Elapsed time: 355.42534 msecs"
39992

Isso é um pouco decepcionante desempenho, e um olhar superficial no(source clojure.set/intersection) não parece mostrar nenhum tratamento especial pelo fato de esses conjuntos serem classificados.

Questão 2: Existe uma maneira melhor / mais rápida de realizar a interseção desorted-sets do queclojure.set/intersection?

(defn intersect-sorted-vector [x y] 
  (loop [x (seq x) y (seq y) acc []] 
    (if (and x y)
      (let [x1 (first x) 
            y1 (first y)] 
      (cond 
        ( < x1 y1) (recur (next x) y acc) 
        ( > x1 y1) (recur x (next y) acc) 
        :else (recur (next x) (next y) (conj acc x1))))
    acc)))

Isso acaba sendo um bom negócio (quase 10x) mais rápido.

user=> (time (count (intersect-sorted-vector x y)))
"Elapsed time: 40.142532 msecs"
39992

Mas não posso deixar de sentir que meu código é indevidamente processual / iterativo.

Questão 3: Alguém poderia gentilmente sugerir uma maneira mais idiomática de processar um par de vetores no Clojure?

questionAnswers(1)

yourAnswerToTheQuestion