Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

More benchmarks; refactor bigtest into benchmark

  • Loading branch information...
commit 6b33e9fc62922ffbe15ae0d9a811eb00af14050e 1 parent 693ee17
Mike Thvedt authored
21 benchmark/clearley/benchmark/json/test.clj
View
@@ -1,21 +0,0 @@
-(ns clearley.benchmark.json.test
- (require [clojure.java.io :as io]
- [clearley.examples.json :as json])
- (use [clearley core]
- [criterium core]))
-
-(def prefix "clearley/benchmark/json/")
-
-(defn bench-parser [filename]
- (println "Loading" filename "into memory")
- (let [loaded-file (-> (str prefix filename)
- io/resource io/reader slurp)]
- (println "Chars loaded:" (count loaded-file))
- (println "Benchmarking")
- (bench (parse json/json-parser loaded-file))))
-
-(defn -main [& args]
- (bench-parser "small-test.json")
- ; With no lookahead, each consecutive space adds O(1) ambiguity
- (bench-parser "small-test-formatted.json")
- )
0  ...clearley/benchmark/json/small-test-formatted.json → ...mark/clearley/benchmark/small-test-formatted.json
View
File renamed without changes
0  benchmark/clearley/benchmark/json/small-test.json → benchmark/clearley/benchmark/small-test.json
View
File renamed without changes
58 benchmark/clearley/benchmark/test.clj
View
@@ -0,0 +1,58 @@
+(ns clearley.benchmark.test
+ (require [clojure.java.io :as io]
+ [clearley.examples.json :as json]
+ [clearley.examples.calculator :as calc])
+ (use [clearley core]
+ [criterium core]))
+
+(def prefix "clearley/benchmark/")
+
+(defn print-sep []
+ (println (apply str (repeat 80 \=))))
+
+(defn bench-str [name parser str]
+ (println "Benchmark:" name)
+ (println "Input size:" (count str))
+ (if-let [r (parse parser str)]
+ (do
+ (println "Benchmarking")
+ (bench (parse parser str))
+ (print-sep))
+ (println "!!!!Failure to parse!!!!")))
+
+(defn bench-from-file [name parser filename]
+ (println "Loading" filename "into memory")
+ (let [loaded-file (-> (str prefix filename)
+ io/resource io/reader slurp)]
+ (bench-str name parser loaded-file)))
+
+(defrule S
+ ([(s1 S) (s2 S)] (str s1 s2))
+ ([(s1 S) (s2 S) (s3 S)] (str s1 s2 s3))
+ ([\s] "s"))
+
+(def pathological-parser-1 (build-parser S))
+
+(defn -main [& args]
+ (print-sep)
+ ; Start with some microbenchmarks
+ (bench-str "Left-recursive calculator" calc/my-calculator "1+2+3+4+5+6+7+8")
+ ; Should have linear growth
+ (bench-str "Left-recursive calculator 2"
+ calc/my-calculator "1+2+3+4+5+6+7+8+1+2+3+4+5+6+7+8")
+ (bench-str "Right-recursive calculator" calc/my-calculator "1^2^3^4^5^6^7^8")
+ ; This has quadratic growth without lookahead, linear growth with it.
+ (bench-str "Right-recursive calculator 2"
+ calc/my-calculator "1^2^3^4^5^6^7^8^1^2^3^4^5^6^7^8")
+ ; Snakes... why did it have to be snakes?
+ ; This is a quadratic grammar, but can incur O(n^4) parse time in some GLR impls. is a quadratic grammar, but can incur O(n^4) parse time in some GLR impls.
+ ; TODO: add a cubic grammar.
+ (bench-str "Pathological grammar 1.1" pathological-parser-1 (repeat 20 \s))
+ (bench-str "Pathological grammar 1.2" pathological-parser-1 (repeat 40 \s))
+ (bench-str "Pathological grammar 1.3" pathological-parser-1 (repeat 80 \s))
+
+ ; JSON grammar is relatively complex--LR parsers should tend to do well
+ (bench-from-file "JSON" json/json-parser "small-test.json")
+ ; With no lookahead, each consecutive space adds O(1) ambiguity
+ (bench-from-file "Formatted JSON" json/json-parser "small-test-formatted.json")
+ )
27 bigtest/clearley/bigtest.clj
View
@@ -1,27 +0,0 @@
-(ns clearley.bigtest
- (:use clearley.core clojure.test))
-
-; Test a grammar that should be O(n^3)
-
-(defrule S
- ([(s1 S) (s2 S)] (str s1 s2))
- ([\s] "s"))
-
-(def s-parser (build-parser S))
-
-(deftest combinatorial-explosion-test
- ; If state reduction works, should execute in O(n^3)
- ; An NDFA without state reduction will see exponential blowup
- (is (parse s-parser
- "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss")))
-; Snakes... why did it have to be snakes?
-
-(extend-rule S
- ([(s1 S) (s2 S) (s3 S)] (str s1 s2 s3)))
-
-(def s-parser-2 (build-parser S))
-
-; TODO
-(deftest big-O-test
- (is (parse s-parser
- "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss")))
7 project.clj
View
@@ -1,12 +1,11 @@
(defproject clearley "0.1.1.ALPHA-SNAPSHOT"
- :description "FIXME: write description"
+ :description "Parsing for Earthlings"
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/math.numeric-tower "0.0.1" :scope "test"]
[com.stuartsierra/lazytest "2.0.0-SNAPSHOT" :scope "test"]
[criterium "0.3.1" :scope "test"]]
- :profiles {:bigtest {:test-paths ["bigtest"]}
- :benchmark {:source-paths ["benchmark" "test"]
+ :profiles {:benchmark {:source-paths ["benchmark" "test"]
:resource-paths ["benchmark"]
- :main clearley.benchmark.json.test}}
+ :main clearley.benchmark.test}}
:repositories {"stuartsierra-releases" "http://stuartsierra.com/maven2"
"stuartsierra-snapshots" "http://stuartsierra.com/m2snapshots"})
5 src/clearley/npda.clj
View
@@ -14,6 +14,8 @@
; Things for a non-deterministic pushdown automaton (an NPDA).
; An NDPA state is a (node, stack, output-stream) tuple.
+; The output streams are partial, containing only the output emitted while
+; that state was on the stack.
;
; The input stream is the same for all active states. Each node may 'shift'
; by consuming input and returning a new node. This node is placed
@@ -181,8 +183,7 @@
(defn run-automaton [initial-node input tokenizer]
(run-automaton-helper input (initial-chart initial-node) tokenizer))
-; TODO rename
-#_(defn run-automaton-2 [initial-node input tokenizer]
+#_(defn fast-run-automaton [initial-node input tokenizer]
(loop [remaining-input input
current-chart (initial-chart initial-node)]
(if-let [thechar (first remaining-input)]
Please sign in to comment.
Something went wrong with that request. Please try again.