compiler/PetitBenchmark.st
changeset 391 553a5456963b
child 392 9b297f0d949c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PetitBenchmark.st	Sun Oct 26 01:03:31 2014 +0000
@@ -0,0 +1,306 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+Object subclass:#PetitBenchmark
+	instanceVariableNames:'sources report contextClass compile'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Benchmarks'
+!
+
+PetitBenchmark comment:''
+!
+
+!PetitBenchmark methodsFor:'benchmark support'!
+
+createContext
+	^ contextClass new
+!
+
+endSuite
+!
+
+initialize
+	super initialize.
+	sources := PetitBenchmarkSources new.
+	contextClass := PPCContext.
+	compile := false.
+!
+
+measure: parser on: input
+	self measure: parser on: input name: #unknown
+!
+
+measure: parser on: input name: aString
+	| time result context p |
+	context := self createContext.
+	
+	compile 	ifTrue: [ 
+					p := (parser end compile: #TmpBenchmark) 
+				] ifFalse: [ 
+					p := parser end. 
+				].
+
+	
+	time := Time millisecondsToRun: [ result := p parse: input withContext: context ].
+
+	self assert: result isPetitFailure not.
+	self reportFor: parser context: context input: input time: time name: aString.
+!
+
+measure: parser onSources: inputs name: aString
+	| time result context p totalInput |
+	
+	compile 	ifTrue: [ 
+					p := (parser end compile: #TmpBenchmark) 
+				] ifFalse: [ 
+					p := parser end. 
+				].
+			
+	totalInput := ''.
+	time := 0.
+	inputs do: [:input | 
+		context := self createContext.
+		time := time + (Time millisecondsToRun: [ result := p parse: input withContext: context ]).
+		totalInput := totalInput, input.
+		self assert: result isPetitFailure not.
+	].
+	
+	
+	self reportFor: parser context: context input: totalInput time: time name: aString.
+!
+
+reportFor: parser context: context input: input time: time
+	self reportFor: parser context: context input: input time: time name: #unknown
+!
+
+reportFor: parser context: context input: input time: time name: name
+	Transcript crShow: (self getMetaInfo: name).
+	Transcript crShow: '	Compile: ', compile asString.	
+	
+	Transcript crShow: '	Total time: ', time asString, ' ms'.
+		
+	Transcript crShow: '	Time per character: ', 
+	(((time / input size) asFloat * 1000) asString truncateTo: 6), 
+	' microseconds'.
+	
+	Transcript crShow: '	Backtrack per character: ',
+	((context backtrackCount / input size) asFloat asString truncateTo: 6),
+	'.'.
+	
+	Transcript crShow: '	Remembers per character: ',
+	((context rememberCount / input size) asFloat asString truncateTo: 6),
+	'.'.
+!
+
+startSuite
+	Transcript crShow: Date current asString, ' ', Time current asString.
+! !
+
+!PetitBenchmark methodsFor:'benchmarks'!
+
+benchmarkAnyStar
+"
+	self measure: self anyStar on: sources petitParserPackage.
+"	
+	self measure: self anyStar on: (self changesSized: 1000*1000) name: #anyStar.
+!
+
+benchmarkAttributes
+	| string text allStyles |
+	string := (self changesSized: 60000).
+	text := string asText.
+	allStyles := {
+		'Announcement' -> TextColor green. 
+		'Collections' -> TextColor blue.
+		'File' -> TextColor blue.
+ 		'Metacello' -> TextColor red.
+		'Monticello' -> TextColor magenta.
+		'Morphic' -> TextColor orange.
+		'Mooose' -> TextColor green.
+		'FAMIX' -> TextColor green.
+		'Roassal' -> TextColor green.
+	}.
+	
+	allStyles do: [ :assoc | | parser result time |
+		parser := (assoc key asParser, #newline asParser negate star).
+		time := Time millisecondsToRun: [
+			result := parser matchingRangesIn: string.
+		].
+		self reportFor: parser input: string time: time.
+	].
+!
+
+benchmarkBacktrack
+"
+	self measure: self anyStar on: sources petitParserPackage.
+"	
+	| parser |
+	parser := ((#any asParser, 'foo' asParser) / self tokenParser / #any asParser) plus.
+	self measure: parser on: (self changesSized: 100*1000) name: #backtrack.
+!
+
+benchmarkJava
+	| parser |
+	parser := PPJavaParser new.
+	self measure: parser on: sources javaLangMath name: #java.
+!
+
+benchmarkNegate
+"
+	self measure: self anyStar on: sources petitParserPackage.
+"	
+	| parser |
+	parser := ('a' asParser negate star, 'a' asParser) star, #any asParser star.
+	self measure: parser on: (self changesSized: 1000*1000) name: #negate.
+!
+
+benchmarkOpalCompiler
+	| parser time input |
+	parser := OpalCompiler new.
+	input := sources smalltalkSourcesBig.
+	time := [ input do: [ :source | parser parse: source ]] timeToRun asMilliseconds.
+	
+	self reportInput: input time: time name: 'Opal'
+!
+
+benchmarkSmalltalkGrammar
+	| parser time input context |
+	parser := PPSmalltalkGrammar new.
+	context := PPContext new.
+	context initializeFor: parser.
+	input := sources smalltalkSourcesBig.
+
+	time := [ input do: [ :source | parser parse: source withContext: context ]] timeToRun asMilliSeconds.
+	
+	self reportInput: input time: time name: 'Smalltalk Grammar'.
+!
+
+benchmarkSmalltalkGrammarCompiled
+	| parser time input context  |
+	parser := PPSmalltalkGrammar new compile.
+	context := PPCContext new.
+	context initializeFor: parser.
+	input := sources smalltalkSourcesBig.
+
+	time := [ input do: [ :source | parser parse: source withContext: context ]] timeToRun asMilliSeconds.
+	
+	self reportInput: input time: time name: 'Compiled Grammar'.
+
+"	
+	size := input inject: 0 into: [:r :e | r + e size  ].
+	Transcript crShow: 'Compiled Grammar time: ', time asString.
+	Transcript crShow: 'Time per character: ', (time / size * 1000.0) asString, ' microseconds'.
+"
+!
+
+benchmarkSmalltalkObject
+	| parser |
+	parser := PPSmalltalkGrammar new.
+	self measure: parser onSources: sources smalltalkObjectMethods name: #smalltalkObject.
+!
+
+benchmarkSmalltalkParser
+	| parser time input context |
+	parser := PPSmalltalkParser new.
+	context := PPContext new.
+	context initializeFor: parser.
+	input := sources smalltalkSourcesBig.
+
+	time := [ input do: [ :source | parser parse: source withContext: context ]] timeToRun asMilliSeconds.
+	
+	self reportInput: input time: time name: 'Smalltalk Parser'.
+!
+
+benchmarkSmalltalkParserCompiled
+	| parser time input context |
+	parser := PPSmalltalkParser new compile.
+	context := PPCContext new.
+	context initializeFor: parser.
+	input := sources smalltalkSourcesBig.
+
+	time := [ input do: [ :source | parser parse: source withContext: context ]] timeToRun asMilliSeconds.
+	
+		self reportInput: input time: time name: 'Smalltalk Parser Compiled'.
+!
+
+benchmarkToken
+"
+	self measure: self anyStar on: sources petitParserPackage.
+"	
+	| parser |
+	parser := (self tokenParser / #any asParser) star.
+	self measure: parser on: (self changesSized: 1000*1000) name: #token.
+!
+
+reportInput: input time: time name: name
+	| size |
+	size := input inject: 0 into: [:r :e | r + e size  ].
+	Transcript crShow: 'Size: ', size asString.
+	Transcript crShow: name, ' time: ', time asString.
+	Transcript crShow: 'Time per character: ', (time / size * 1000.0) asString, ' microseconds'.
+! !
+
+!PetitBenchmark methodsFor:'meta'!
+
+getMetaInfo: key
+	| info |
+	info := self metaInfo select: [ :each | each key = key ].
+	info isEmpty ifTrue: [ ^ 'unknown benchmark' ].
+	^ info anyOne value
+!
+
+metaInfo
+	^ { 
+		#anyStar -> '.* Parser'.
+		#token -> 'Token Parser'.
+		#backtrack -> 'Backtracking Parser'.
+		#negate -> 'Negate Parser'.
+		#java -> 'Standard Java Parser'.
+		#smalltalkObject -> 'All Smalltalk Object methods'
+	}
+! !
+
+!PetitBenchmark methodsFor:'parsers'!
+
+anyStar
+	^ #any asParser star
+!
+
+tokenParser
+	^ #letter asParser, (#letter asParser / #digit asParser) star trim
+! !
+
+!PetitBenchmark methodsFor:'settings'!
+
+compile: aBoolean
+	compile := aBoolean
+!
+
+contextClass: aClass
+	contextClass := aClass
+! !
+
+!PetitBenchmark methodsFor:'sources'!
+
+changesSized: size
+	| string changes |
+	changes := PharoFilesOpener default changesFileOrNil contents.
+	string :=  changes copyFrom: 1 to: size.
+	^ string
+	
+! !
+
+!PetitBenchmark methodsFor:'suites'!
+
+suite1
+	self startSuite.
+	
+	self benchmarkNegate.
+	self benchmarkBacktrack.
+	self benchmarkToken.
+	self benchmarkAnyStar.
+	self benchmarkJava.
+	
+	self endSuite.
+! !
+