Note that there are some explanatory texts on larger screens.

plurals
  1. POFollow-up to "Simple String template replacement in Scala and Clojure"
    text
    copied!<p>In my previous <a href="https://stackoverflow.com/questions/6110062/simple-string-template-replacement-in-scala-and-clojure">post</a>, I showed a simple (naive) algorithm for doing a String template replacement.</p> <p>One of the solutions, provided by <a href="https://stackoverflow.com/users/214010/mikera">mikera</a>, seems like a much better algorithm. I implemented it in Clojure (follows) and timed it against my previous algorithm. The new one is <strong>slower</strong> (41.475 msecs vs. 19.128 msecs) on 100 runs. I must be doing something stupid in my new implementation.</p> <pre><code>(defn replace-templates "Return a String with each occurrence of a substring of the form {key} replaced with the corresponding value from a map parameter. @param str the String in which to do the replacements @param m a map of keyword-&gt;value" [text m] (let [builder (StringBuilder.) text-length (.length text)] (loop [current-index 0] (if (&gt;= current-index text-length) (.toString builder) (let [open-brace (.indexOf text "{" current-index)] (if (&lt; open-brace 0) (.toString (.append builder (.substring text current-index))) (let [close-brace (.indexOf text "}" open-brace)] (if (&lt; close-brace 0) (.toString (.append builder (.substring text current-index))) (do (.append builder (.substring text current-index open-brace)) (.append builder (let [key (keyword (.substring text (inc open-brace) close-brace)) replacement (m key)] (if (nil? replacement) "" replacement))) (recur (inc close-brace))))))))))) </code></pre> <p>although it passes all test cases:</p> <pre><code>(use 'clojure.test) (deftest test-replace-templates (is (= (replace-templates "this is a test" {:foo "FOO"}) "this is a test")) (is (= (replace-templates "this is a {foo} test" {:foo "FOO"}) "this is a FOO test")) (is (= (replace-templates "this is a {foo} test {bar}" {:foo "FOO" :bar "BAR"}) "this is a FOO test BAR")) (is (= (replace-templates "this is a {foo} test {bar} 42" {:foo "FOO" :bar "BAR"}) "this is a FOO test BAR 42")) (is (= (replace-templates "this is a {foo} test {bar" {:foo "FOO" :bar "BAR"}) "this is a FOO test {bar"))) ; user=&gt; Ran 1 tests containing 5 assertions. ; user=&gt; 0 failures, 0 errors. ; user=&gt; {:type :summary, :test 1, :pass 5, :fail 0, :error 0} </code></pre> <p>Here is the test code:</p> <pre><code>(time (dotimes [n 100] (replace-templates "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elit nisi, egestas et tincidunt eget, {foo} mattis non erat. Aenean ut elit in odio vehicula facilisis. Vestibulum quis elit vel nulla interdum facilisis ut eu sapien. Nullam cursus fermentum sollicitudin. Donec non congue augue. {bar} Vestibulum et magna quis arcu ultricies consectetur auctor vitae urna. Fusce hendrerit facilisis volutpat. Ut lectus augue, mattis {baz} venenatis {foo} lobortis sed, varius eu massa. Ut sit amet nunc quis velit hendrerit bibendum in eget nibh. Cras blandit nibh in odio suscipit eget aliquet tortor placerat. In tempor ullamcorper mi. Quisque egestas, metus eu venenatis pulvinar, sem urna blandit mi, in lobortis augue sem ut dolor. Sed in {bar} neque sapien, vitae lacinia arcu. Phasellus mollis blandit commodo." {:foo "HELLO" :bar "GOODBYE" :baz "FORTY-TWO"}))) ; user=&gt; "Elapsed time: 41.475 msecs" ; user=&gt; nil </code></pre> <p>I wonder if the problem is the continuous reallocation of the <code>StringBuilder</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload