Commits

Karsten Schmidt  committed 7e210dd

initial check in

  • Participants

Comments (0)

Files changed (8)

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="test">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="dev-resources">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="resources">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="lib" path="target/classes">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="ccw.LEININGEN_CONTAINER"/>
+	<classpathentry kind="lib" path="classes"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
+syntax: glob
+bin
+classes
+target
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>macrochrono</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>ccw.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>ccw.leiningen.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>ccw.leiningen.nature</nature>
+		<nature>ccw.nature</nature>
+	</natures>
+</projectDescription>
+# macrochrono
+
+A small collection of time measuring & benchmarking macros for Clojure.
+
+## Usage
+
+Leiningen dependency:
+
+	[com.postspectacular/macrochrono "0.1.0"]
+
+There are currently only two macro available to measure a single execution or
+to benchmark a number of iterations. In both cases the timings are given in
+milliseconds. `timed-action` returns a 2-element vector of the expression's
+result followed by its execution time.
+
+	(use 'macrochrono)
+	(timed-action (reduce + (range 1 100001)))
+	[5000050000 5.784]
+
+The `bench` macro evaluates a given expression several times, discards the result
+and returns a map of execution time statistics:
+
+	(bench 1000 (reduce + (range 1 100001)))
+	{:median 5.1579999999999995, :max 9.091, :min 4.677, :avg 5.633388000000003}
+
+Adding an additional "verbose" flag, each intermediate timing is printed to *out*.
+
+	(bench 10 (reduce + (range 1 100001)) true)
+	"Elapsed time: 6.021 msecs"
+	"Elapsed time: 8.251 msecs"
+	"Elapsed time: 5.162999999999999 msecs"
+	"Elapsed time: 5.269 msecs"
+	"Elapsed time: 6.8759999999999994 msecs"
+	"Elapsed time: 8.251999999999999 msecs"
+	"Elapsed time: 6.112 msecs"
+	"Elapsed time: 5.0169999999999995 msecs"
+	"Elapsed time: 6.927 msecs"
+	"Elapsed time: 5.637 msecs"
+	{:median 6.112, :max 8.251999999999999, :min 5.0169999999999995, :avg 6.3525}
+
+## License
+
+Copyright © 2012 Karsten Schmidt
+
+Distributed under the Eclipse Public License, the same as Clojure.
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.postspectacular</groupId>
+  <artifactId>macrochrono</artifactId>
+  <packaging>jar</packaging>
+  <version>0.1.0</version>
+  <name>macrochrono</name>
+  <description>A small collection of time measuring &amp; benchmarking macros.</description>
+  <url>http://hg.postspectacular.com/macrochrono</url>
+  <licenses>
+    <license>
+      <name>Eclipse Public License</name>
+      <url>http://www.eclipse.org/legal/epl-v10.html</url>
+      <distribution>repo</distribution>
+      <comments>same as Clojure</comments>
+    </license>
+  </licenses>
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+    <resources>
+      <resource>
+        <directory>resources</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>dev-resources</directory>
+      </testResource>
+      <testResource>
+        <directory>resources</directory>
+      </testResource>
+    </testResources>
+    <directory>target</directory>
+    <outputDirectory>target/classes</outputDirectory>
+  </build>
+  <repositories>
+    <repository>
+      <id>central</id>
+      <url>http://repo1.maven.org/maven2</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+    </repository>
+    <repository>
+      <id>clojars</id>
+      <url>https://clojars.org/repo/</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+    </repository>
+  </repositories>
+  <dependencies>
+    <dependency>
+      <groupId>org.clojure</groupId>
+      <artifactId>clojure</artifactId>
+      <version>1.4.0</version>
+    </dependency>
+  </dependencies>
+</project>
+
+<!-- This file was autogenerated by Leiningen.
+  Please do not edit it directly; instead edit project.clj and regenerate it.
+  It should not be considered canonical data. For more information see
+  https://github.com/technomancy/leiningen -->
+(defproject com.postspectacular/macrochrono "0.1.0"
+  :description "A small collection of time measuring & benchmarking macros."
+  :url "http://hg.postspectacular.com/macrochrono"
+  :license {:name "Eclipse Public License"
+            :url "http://www.eclipse.org/legal/epl-v10.html"
+            :distribution :repo
+            :comments "same as Clojure"}
+  :dependencies [[org.clojure/clojure "1.4.0"]])

File src/macrochrono.clj

+(ns macrochrono
+  "A collection of time measuring & benchmarking macros."
+  {:author "Karsten Schmidt"})
+
+(defmacro timed-action
+  "Evaluates body in a do form and measures execution time.
+  Returns result as 2-element vector: [body-result time-in-msecs]"
+  [& body]
+  `(let [t0# (System/nanoTime)]
+     [(do ~@body) (* 1e-6 (- (System/nanoTime) t0#))]))
+
+(defmacro bench
+  "Evaluates body num times and returns map of execution time statistics:
+  average, min, max and median times (all in ms). The result of the body
+  expression is discarded. If verbose? is truthy, each intermediate timing
+  is printed to *out*."
+  ([num body] `(bench ~num ~body false))
+  ([num body verbose?]
+  `(loop [stats# [] i# ~num]
+     (if (pos? i#)
+       (let[[res# taken#] (timed-action ~body)]
+         (if ~verbose? (prn (str "Elapsed time: " taken# " msecs")))
+         (recur (conj stats# taken#) (dec i#)))
+       {:avg (/ (reduce + stats#) ~num)
+        :min (reduce min stats#)
+        :max (reduce max stats#)
+        :median (nth (sort stats#) (int (/ ~num 2)))}))))

File test/macrochrono/core_test.clj

+(ns macrochrono.core-test
+  (:use clojure.test
+        macrochrono.core))
+
+(deftest a-test
+  (testing "FIXME, I fail."
+    (is (= 0 1))))