         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


(defprotocol JSONWriter
  (-write [object out options]
    "Print object to PrintWriter out as JSON"))

(defn- ->hex-string [^PrintWriter out cp]
  (let [cpl (long cp)]
    (.write out "\\u")
    (cond
      (< cpl 16)
      (.write out "000")
      (< cpl 256)
      (.write out "00")
      (< cpl 4096)
      (.write out "0"))
    (.write out (Integer/toHexString cp))))

(def ^{:tag "[S"} codepoint-decoder
  (let [shorts (short-array 128)]

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

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

(defn- write-bignum [x ^Appendable out options]
  (.append out (str x)))

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

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

(defn- write-plain [x ^Appendable out options]
  (.append out (str x)))

(defn- write-null [x ^Appendable out options]
  (.append out "null"))

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