diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b5be10c..c3583870 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,6 +121,11 @@ jobs: fi done + if [ ! -d som-vm ]; then + echo "All clone attempts failed, falling back to SOM-st" + git clone --depth 1 https://github.com/SOM-st/$REPO som-vm + fi + - name: Install Apt Packages if: ${{ matrix.apt != '' }} run: | diff --git a/Examples/Benchmarks/Knapsack.som b/Examples/Benchmarks/Knapsack.som new file mode 100644 index 00000000..2c8a8e20 --- /dev/null +++ b/Examples/Benchmarks/Knapsack.som @@ -0,0 +1,75 @@ +Knapsack = Benchmark ( + getWeights = ( + | weights prng | + weights := Vector new. + prng := Random new. + + 1 to: 100 do: [:w | | repetitions | + repetitions := prng next % 50 + 20. + repetitions timesRepeat: [ + weights append: w. + weights size = 5000 ifTrue: [ + ^ weights ] ] ]. + + [ weights size < 5000 ] whileTrue: [ + weights append: 100 ]. + + ^ weights + ) + + getRandomValues = ( + | values prng i | + values := Vector new. + prng := Random new. + + 5000 timesRepeat: [ + values append: prng next % 100 ]. + + ^ values + ) + + innerBenchmarkLoop: goal = ( + | ws vs result expectedResult eI | + ws := self getWeights. + vs := self getRandomValues. + + result := self knapsack: goal weights: ws values: vs. + 'result: ' print. result println. + + expectedResult := #(99 2226 3431 4289 4946 5520 6044 6530 7000 7435 7844 8244 8634 9018 + 9392 9751 10105 10453 10797 11133 11465 11793 12118 12438 12749 + 13056 13360 13659 13953 14242 14527 14805 15079 15348 15613 15875 + 16133 16388 16638 16887 17132). + eI := goal / 25 + 1. + + "Remember: this is a bit brittle, and while the `expectedResults` where generated by this code + there seem to be cases where the below doesn't hold. + So, not all problem sizes will validate, but seems good enough for now." + eI + 1 <= expectedResult length + ifTrue: [ + ^ result >= (expectedResult at: eI) and: [ result <= (expectedResult at: eI + 1) ] ] + ifFalse: [ + ^ result > expectedResult last ] + ) + + knapsack: goal weights: w values: v = ( + | m | + ((w size <= 0) || (goal <= 0)) ifTrue: [ ^ 0 ]. + + m := Vector new. + 1 to: 1 + w size do: [ :i | + m append: Vector new. + 1 to: 1 + goal do: [ :j | + (m at: i) append: 0 ] ]. + + 1 to: w size do: [ :i | + 1 to: goal do: [ :j | + (w at: i) > j + ifTrue: [ (m at: i + 1) at: j + 1 put: ((m at: i) at: j + 1) ] + ifFalse: [ (m at: i + 1) at: j + 1 put: (((m at: i) at: j + 1) max: (((m at: i) at: j + 1 - (w at: i)) + (v at: i))) ] + ] + ]. + + ^ (m at: w size) last + ) +) diff --git a/Examples/Benchmarks/VectorBenchmark.som b/Examples/Benchmarks/VectorBenchmark.som new file mode 100644 index 00000000..dba9de5f --- /dev/null +++ b/Examples/Benchmarks/VectorBenchmark.som @@ -0,0 +1,23 @@ +"A benchmark to exercise #, , #remove: , and #at:put: of the Vector class" +VectorBenchmark = Benchmark ( + + benchmark = ( + | v | + + "Create a vector and add 1000 items to it" + v := Vector new. + 1 to: 1000 do: [ :i | v, i]. + + "Remove 100 items from the middle" + 450 to: 550 do: [:i | v remove: i]. + + "Now change the terms located from 350 to 450" + 350 to: 450 do: [:i | v at: i put: i+1]. + + ^v + ) + + verifyResult: result = ( + ^ self assert: 351 equals: (result at: 350) + ) +) diff --git a/TestSuite/VectorTest.som b/TestSuite/VectorTest.som index 130601bd..9b638026 100644 --- a/TestSuite/VectorTest.som +++ b/TestSuite/VectorTest.som @@ -251,7 +251,20 @@ VectorTest = TestCase ( self assert: 2 equals: (arr at: 1). self assert: 5 equals: (arr at: 2). ) - + + "Check that asArray copies storage and a later access does not overwrite the vec's content" + testAsArrayEnsureItCopiesStorageArray = ( + | vec arr | + vec := Vector new. + vec append: 1. + vec append: 2. + + arr := vec asArray. + arr at: 1 put: 44. + + self assert: (vec at: 1) equals: 1. + ) + testAsSet = ( | v set | v := Vector new. @@ -401,4 +414,16 @@ VectorTest = TestCase ( ]. self assert: 6 equals: i. ) + + "doIndexes iterates from 1 rather then start check core-lib/Vector implementation" + testDoIndexesDoubleRemove = ( + | v | + v := Vector new. + 1 to: 10 do: [:i | v , i]. + + v removeFirst. + v removeFirst. + + v doIndexes: [:i | self assert: i equals: ((v at: i)-2)] + ) )