         returns itself, the key-value pair will be omitted from the
         output. This option does not apply to non-map collections."
   [x ^Writer writer & options]
-  (-write x (PrintWriter. writer) (merge default-write-options (apply array-map options))))
+  (-write x writer (merge default-write-options (apply array-map options))))
 
 (defn write-str
   "Converts x to a JSON-formatted string. Options are the same as
   write."
   [x & options]
-  (let [sw (StringWriter.)]
-    (-write x (PrintWriter. sw) (merge default-write-options (apply array-map options)))
+  (let [sw (StringBuilder.)]
+    (-write x sw (merge default-write-options (apply array-map options)))
     (.toString sw)))
 
 ;;; JSON PRETTY-PRINTER

          (if-not (= value-fn out-value)
            (do
              (when have-printed-kv
                (.print out \,))
              (write-string out-key out options)
              (.print out \:)
              (-write out-value out options)
              (when (seq nxt)
                (recur nxt true)))
            (when (seq nxt)
              (recur nxt have-printed-kv)))))))
  (.print out \}))

(defn- write-array [s ^PrintWriter out options]
  (.print out \[)
  (loop [x s]
    (when (seq x)
      (let [fst (first x)
            nxt (next x)]
        (-write fst out options)
        (when (seq nxt)
          (.print out \,)
          (recur nxt)))))
  (.print out \]))

(defn- write-bignum [x ^PrintWriter out options]
  (.print out (str x)))

(defn- write-float [^Float x ^PrintWriter out options]
  (cond (.isInfinite x)
        (throw (Exception. "JSON error: cannot write infinite Float"))
        (.isNaN x)
        (throw (Exception. "JSON error: cannot write Float NaN"))
        :else
        (.print out x)))

(defn- write-double [^Double x ^PrintWriter out options]
  (cond (.isInfinite x)
        (throw (Exception. "JSON error: cannot write infinite Double"))
        (.isNaN x)
        (throw (Exception. "JSON error: cannot write Double NaN"))
        :else
        (.print out x)))

(defn- write-plain [x ^PrintWriter out options]
  (.print out x))

(defn- write-null [x ^PrintWriter out options]
  (.print out "null"))

(defn- write-named [x out options]
  (write-string (name x) out options))

          (aset shorts i (short 0)))))
    shorts))

(defn- write-string [^CharSequence s ^Appendable out options]
  (let [decoder codepoint-decoder]
    (.append out (codepoint \"))
    (dotimes [i (.length s)]
      (let [cp (int (.charAt s i))]
        (if (< cp 128)
          (case (aget decoder cp)
            0 (.append out cp)
            1 (do (.append out (codepoint \\)) (.append out cp))
            2 (.append out (if (get options :escape-slash) "\\/" "/"))
            3 (.append out "\\b")
            4 (.append out "\\f")
            5 (.append out "\\n")
            6 (.append out "\\r")
            7 (.append out "\\t")
            8 (->hex-string out cp))
          (codepoint-case cp
            :js-separators (if (get options :escape-js-separators)
                             (->hex-string out cp)
                             (.append out cp))
            (if (get options :escape-unicode)
              (->hex-string out cp) ; Hexadecimal-escaped
              (.append out cp))))))
    (.append out (codepoint \"))))

(defn- write-object [m ^Appendable out options]
  (let [key-fn (:key-fn options)
        value-fn (:value-fn options)]
    (.append out \{)
    (loop [x m, have-printed-kv false]
      (when (seq x)
        (let [[k v] (first x)
