   (let [empty-qual? (and (= (.length qual) 1)
                          (= (.charAt qual 0) \*))]
     (if empty-qual?
-      (vec (repeat (count idx) 93)) ;; \~
-      (mapv (fn [[_ x]]
-              (if (number? x)
-                (qual/fastq-char->phred-byte (.charAt qual x))
-                93))
-            idx))))
+      (short-array (repeat (count idx) 93)) ;; \~
+      (->> idx
+           (map (fn [[_ x]]
+                  (if (number? x)
+                    (qual/fastq-char->phred-byte (.charAt qual x))
+                    93)))
+           short-array))))
+
+(deftype PosBase [^char base indel])
 
 (defn- seqs-at-ref
   [idx ^String s]
-  (mapv (fn [[op x xs]]
-          (let [c (if (number? x) (.charAt s x) x)]
-            (case op
-              :m [c]
-              :d [c xs]
-              :i [c (subs s (first xs) (last xs))]))) idx))
+  (->> idx
+       (map (fn [[op x xs]]
+              (let [c (if (number? x) (.charAt s x) x)]
+                (case op
+                  :m (->PosBase c nil)
+                  :d (->PosBase c xs)
+                  :i (->PosBase c (subs s (first xs) (last xs)))))))
+       object-array))
 
 (defn index-cigar
   "Align bases and base quality scores with the reference coordinate."

  "Convert a pile into `cljam.io.pileup.LocusPile`."
  [chr [pos pile]]
  (when (seq pile)
    (LocusPile. chr pos pile)))

(defn filter-by-base-quality
  "Returns a predicate for filtering piled-up reads by base quality at its

  [^long min-base-quality]
  (fn [p]
    (->> #(<= min-base-quality (.qual ^PileupBase %))
         (partial filter)
         (update p 1))))

(defn- unzip-2
