title: Average brightness with Clojure very slow
body: <p>Being new to Clojure I would like to compute the average brightness of (lots of) jpg-images. To do so I load the image into memory using <code>ImageIO/read</code> from Java, extract the byte buffer behind it and apply an average.</p>
  
  <pre><code>(defn brightness
    "Computes the average brightness of an image."
    [^File file]
    (-&gt; file
      ImageIO/read
      .getRaster
      .getDataBuffer
      .getData
      byteaverage))
  </code></pre>
  
  <p>Here, the average</p>
  
  <pre><code>(defn byteaverage
    [numbers]
    (/ (float
       (-&gt;&gt; numbers
          (map bytetoint)
          (apply +)))
       (count numbers))
    )
  </code></pre>
  
  <p>needs to take into account that bytes are signed in Java and need to be converted to sufficiently large integers first.</p>
  
  <pre><code>(defn bytetoint
     [b]
     (bit-and b 0xFF)
    )
  </code></pre>
  
  <p>While this does give correct results, it is extremely slow. It takes around 10 to 20 seconds for 20 megapixel images. Disk access is not the problem. From playing around with <code>time</code>, the culprit seems to be the <code>bytetoint</code> conversion. Just mapping this <code>bytetoint</code> onto the byte array eats 8 GB of memory and does not terminate in the REPL.</p>
  
  <p>Why is that and what could one do about it?</p>
  
  <p>PS: I am aware that one could use other programming languages, libraries, multithreading or change the algorithm. My point is that the above Clojure code <em>should</em> be much faster and I would like to understand why it is not.</p>