k-nucleotide Pharo Smalltalk #5 program
source code
"* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
contributed by Andres Valloud
modified by Isaac Gouy for Pharo *"!
Object subclass: #BenchmarksGame
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: ''!
!SequenceableCollection methodsFor: 'benchmarks game'!
substringFrequencies: aLength using: aDictionary
| buffer |
buffer := String new: aLength.
1 to: self size - aLength + 1 do:
[:i |
| answer |
buffer replaceFrom: 1 to: aLength with: self startingAt: i.
answer := aDictionary
at: buffer
putValueOf: [:sum | sum + 1]
ifAbsentPutValueOf: 1.
answer = 1 ifTrue: [buffer := String new: aLength].
].
^aDictionary! !
!Dictionary methodsFor: 'benchmarks game'!
at: key putValueOf: putBlock ifAbsentPutValueOf: absentBlock
"* Set the value at key to be the value of evaluating putBlock
with the existing value. If key is not found, create a new
entry for key and set is value to the evaluation of
absentBlock. Answer the result of evaluating either block. *"
| index element anObject |
key == nil ifTrue:
[^self
subscriptBoundsErrorFor: #at:putValueOf:ifAbsentPutValueOf:
index: key
value: absentBlock value].
index := self findElementOrNil: key.
element := self basicAt: index.
element == nil
ifTrue: [self atNewIndex: index put:
(self createKey: key value: (anObject := absentBlock value))]
ifFalse: [element value: (anObject := putBlock value: element value)].
^anObject! !
!BenchmarksGame class methodsFor: 'private'!
readFasta: sequenceName from: input
| sc gt lf prefix description buffer byte |
sc := $; asciiValue.
gt := $> asciiValue.
lf := Character lf asciiValue.
prefix := '>',sequenceName.
"* find start of particular fasta sequence *"
[(input atEnd) or: [
(input peek = gt)
ifTrue: [((line := (input upTo: lf) asString)
findString: prefix) = 1]
ifFalse: [input skipTo: lf. false].
]
] whileFalse.
"* line-by-line read - it would be a lot faster to block read *"
description := line.
buffer := ReadWriteStream on: (String new: 1028).
[(input atEnd) or: [(byte := input peek) = gt]] whileFalse: [
(byte = sc)
ifTrue: [input upTo: lf]
ifFalse: [buffer nextPutAll: (input upTo: lf) asString]
].
^Association key: description value: buffer contents !
knucleotideFrom: input to: output
"Same as av3, but create less strings while updating the frequencies"
| sequence writeFrequencies writeCount |
sequence := (self readFasta: 'THREE' from: input) value asUppercase.
writeFrequencies :=
[:k | | frequencies count |
frequencies := SortedCollection sortBlock: [:a :b|
(a value = b value) ifTrue: [b key < a key] ifFalse: [b value < a value]].
count := 0.0.
(sequence substringFrequencies: k using: (Dictionary new: 1024))
associationsDo: [:each|
frequencies add: each. count := count + each value].
frequencies do: [:each | | percentage |
percentage := (each value / count) * 100.0.
output
nextPutAll: each key; space;
print: percentage digits: 3; nl]].
writeCount := [:nucleotideFragment | | frequencies count |
frequencies := sequence substringFrequencies: nucleotideFragment size
using: (Dictionary new: 1024).
count := frequencies at: nucleotideFragment ifAbsent: [0].
output print: count; tab; nextPutAll: nucleotideFragment; nl].
writeFrequencies value: 1. output nl.
writeFrequencies value: 2. output nl.
writeCount value: 'GGT'.
writeCount value: 'GGTA'.
writeCount value: 'GGTATT'.
writeCount value: 'GGTATTTTAATT'.
writeCount value: 'GGTATTTTAATTTATAGT'.! !
!BenchmarksGame class methodsFor: 'initialize-release'!
do: n
self knucleotideFrom: Stdio stdin to: Stdio stdout! !
!Stream methodsFor: 'benchmarks game'!
print: number digits: decimalPlaces
| precision rounded |
decimalPlaces <= 0 ifTrue: [^ number rounded printString].
precision := (10 raisedTo: decimalPlaces negated) asFloat.
rounded := number roundTo: precision.
self nextPutAll:
((rounded asScaledDecimal: decimalPlaces) printString copyUpTo: $s)!
nl
self nextPut: Character lf! !
!StdioStream instance methodsFor: 'positioning'!
skipTo: anObject
"Set the access position of the receiver to be past the next occurrence of
anObject. Answer whether anObject is found."
[self atEnd]
whileFalse: [self next = anObject ifTrue: [^true]].
^false! !
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
Pharo 9.0.21
Dec 7 2022 20:44:42
Compiler: 5.4.0 20160609
Mon, 23 Jan 2023 18:16:41 GMT
MAKE:
cp /opt/src/pharo-vm-Linux-x86_64-stable/Pharo10-SNAPSHOT-64bit-2314c3f.image knucleotide.pharo-5.pharo_run.image
cp /opt/src/pharo-vm-Linux-x86_64-stable/Pharo10-SNAPSHOT-64bit-2314c3f.changes knucleotide.pharo-5.pharo_run.changes
ln -s /opt/src/pharo-vm-Linux-x86_64-stable/Pharo10.0-64bit-2314c3f.sources .
cat Include/pharo/make.st
| prog |
(SystemWindow windowsIn: World
satisfying: [:w | w model canDiscardEdits])
do: [:w | w delete].
"load program to be measured"
prog := Smalltalk getSystemAttribute: 3.
(prog notNil) ifTrue: [prog asFileReference fileIn].
ImageCleaner cleanUpForRelease.
Smalltalk garbageCollect.
SmalltalkImage current snapshot: true andQuit: true.
/opt/src/pharo-vm-Linux-x86_64-stable/pharo --headless knucleotide.pharo-5.pharo_run.image Include/pharo/make.st knucleotide.pharo-5.pharo
NewUndeclaredWarning: BenchmarksGame class>>readFasta:from: (line is Undeclared)
NewUndeclaredWarning: BenchmarksGame class>>readFasta:from: (line is Undeclared)
cat Include/pharo/main.st
BenchmarksGame do: (Smalltalk getSystemAttribute: 3) asInteger.!
SmalltalkImage current snapshot: false andQuit: true!
27.41s to complete and log all make actions
COMMAND LINE:
/opt/src/pharo-vm-Linux-x86_64-stable/pharo --headless knucleotide.pharo-5.pharo_run.image Include/pharo/main.st 0 < knucleotide-input250000.txt
PROGRAM FAILED
PROGRAM OUTPUT:
[31mSubscriptOutOfBounds: 289
[0mDictionary(Object)>>errorSubscriptBounds:
Dictionary(Object)>>basicAt:
Dictionary>>at:putValueOf:ifAbsentPutValueOf:
ByteString(SequenceableCollection)>>substringFrequencies:using:
[:k | | frequencies count |
frequencies := SortedCollection sortBlock: [:a :b|
(a value = b value) ifTrue: [b key < a key] ifFalse: [b value < a value]].
count := 0.0.
(sequence substringFrequencies: k using: (Dictionary new: 1024))
associationsDo: [:each|
frequencies add: each. count := count + each value].
frequencies do: [:each | | percentage |
percentage := (each value / count) * 100.0.
output
nextPutAll: each key; space;
print: percentage digits: 3; nl]] in BenchmarksGame class>>knucleotideFrom:to: in Block: [:k | | frequencies count |
frequencies := S...etc...
BenchmarksGame class>>knucleotideFrom:to:
BenchmarksGame class>>do:
UndefinedObject>>DoIt
[ receiver withArgs: (context ifNil: [ #() ] ifNotNil: [ {context} ]) executeMethod: self compileDoit] in OpalCompiler>>evaluate in Block: [ receiver withArgs: (context ifNil: [ #() ] ifNot...etc...
FullBlockClosure(BlockClosure)>>on:do:
OpalCompiler>>evaluate
DoItChunk>>importFor:logSource:
[ :declaration |
requestor ifNotNil: [
requestor contents: declaration contents ].
value := declaration importFor: requestor logSource: logSource ] in CodeImporter>>evaluate in Block: [ :declaration |...
OrderedCollection>>do:
CodeImporter>>evaluate
[ codeImporter evaluate ] in STCommandLineHandler>>installSourceFile: in Block: [ codeImporter evaluate ]
FullBlockClosure(BlockClosure)>>on:do:
STCommandLineHandler>>handleErrorsDuring:reference:
STCommandLineHandler>>installSourceFile:
[ :reference |
self installSourceFile: reference ] in [ sourceFiles do: [ :reference |
self installSourceFile: reference ]
] in STCommandLineHandler>>installSourceFiles in Block: [ :reference | ...
OrderedCollection>>do:
[ sourceFiles do: [ :reference |
self installSourceFile: reference ]
] in STCommandLineHandler>>installSourceFiles in Block: [ sourceFiles do: [ :reference | ...
FullBlockClosure(BlockClosure)>>ensure:
STCommandLineHandler>>installSourceFiles
STCommandLineHandler>>activate
STCommandLineHandler class(CommandLineHandler class)>>activateWith:
[ aCommandLinehandler activateWith: commandLine ] in PharoCommandLineHandler(BasicCommandLineHandler)>>activateSubCommand: in Block: [ aCommandLinehandler activateWith: commandLine ]
FullBlockClosure(BlockClosure)>>on:do:
PharoCommandLineHandler(BasicCommandLineHandler)>>activateSubCommand:
PharoCommandLineHandler(BasicCommandLineHandler)>>handleSubcommand
[0m