Skip to content

Performance & Profiling

Clorch is designed for high-performance deep learning. Because it is built on LibTorch, it executes heavy tensor compute in C++, bypassing the overhead of the JVM for math operations.

Performance Tips

1. Vectorized Operations

Always prefer vectorized tensor operations over manual loops in Clojure.

;; FAST: Executed in C++
(t/add tensor 1.0)

;; SLOW: Crosses the JNI boundary for every element
(mapv #(+ % 1.0) (t/tseq tensor))

2. Contiguous Tensors

Certain operations like view require tensors to be contiguous in memory. If you encounter errors after transposing or slicing, call contiguous.

(-> tensor (t/transpose 0 1) (.contiguous))

3. Using no-grad

During inference, always use autograd/no-grad. This prevents the creation of the autograd graph, significantly reducing memory usage and increasing speed.

(autograd/no-grad
  (nn/forward model x))

Memory Profiling

If you suspect a native memory leak, you can use the built-in profiling tool or JVM tools like jcmd.

Using test/profiler.clj

Clorch includes a profiling script that monitors JVM Heap and Native RSS (Resident Set Size).

clojure -M test/profiler.clj

Manual Monitoring

You can monitor the Resident Set Size (RSS) of your process to see native memory usage:

ps -o rss -p <PID>

If the RSS grows indefinitely while the JVM Heap remains stable, you likely have a missing with-torch scope or a leaked native pointer.

JNI Overhead

Clorch uses JavaCPP to minimize JNI overhead. However, calling a native method still has a small fixed cost. For maximum performance, group your operations into larger tensor calls rather than many small ones.