JMHProcessor.kt 3.7 KB
Newer Older
1
2
3
4
package se.lth.cs

import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
5
6
import org.apache.commons.csv.CSVPrinter
import java.io.*
7
import java.lang.Exception
8
9

class JMHProcessor {
10

11
    fun process(file: File): List<JMHRecord> {
Noric Couderc's avatar
Noric Couderc committed
12
        return process(FileReader(file))
13
14
    }

15
16
17
    data class JMHRecord(val seed : Int, val size : Int, val collection : String, val best : String)

    fun process(reader : Reader): List<JMHRecord> {
18
        var parser = CSVParser(reader, CSVFormat.DEFAULT.withFirstRecordAsHeader())
Noric Couderc's avatar
Noric Couderc committed
19
        // We are grouping the parameters by any parameter except the data structure name (which we want)
20

21
22
23
24
25
        val selectedColumns = listOf(
                "Benchmark",
                "Param: seed",
                "Param: applicationSize"
        )
26
27
28
29
30
31

        val seedsToRecords = parser.records.groupBy { record ->
            selectedColumns.map { column -> record.get(column) }
        }

        return seedsToRecords.values.map { records ->
Noric Couderc's avatar
Noric Couderc committed
32
            val interfaceName = records[0].get("Benchmark").let { processBenchmarkName(it) }
33
            val seed = records[0].get("Param: seed")
34
                    .let { Integer.parseInt(it)}
35
            val size = records[0].get("Param: applicationSize")
36
                    .let { Integer.parseInt(it)}
37
38
39
40
41
42
43
44
45
46
47
            // We need to group the runs by data structure size too.
            // We match the size with the higest score found
            val recordsByBaseSize =
                    records.groupBy { it.get("Param: baseStructureSize") }
                            .mapValues { (k, v) -> v.maxBy { it.get("Score") }}
            // We count the number of times the data structure has won
            // (Computing a histogram of the data structure names)
            val bestScoreHist =
                    recordsByBaseSize.values.groupBy { it!!.get("Param: datastructureName") }
                            .mapValues { (k, v) -> v.size}
            val bestScore = bestScoreHist.maxBy { (k, v) -> v }!!.key
48
49
            // listOf(interfaceName, seed, size, bestScore)
            JMHRecord(seed, size, interfaceName, bestScore)
50
51
        }
    }
52

Noric Couderc's avatar
Noric Couderc committed
53
    class JMHProcessorException(override val message: String?) : Exception(message)
54
55
56
57
58
59
60
61
62

    fun processBenchmarkName(benchmark : String) : String {
        val options = listOf("List", "Map", "Set")
        val name = benchmark.findAnyOf(options)?.second
        if (name.isNullOrBlank()) {
            throw JMHProcessorException("Benchmark name does not contain any of $options")
        }
        return name
    }
63
64
65
66

    /**
     * Prints the given records to a file
     */
67
    fun print(writer : Writer, records : List<JMHRecord>) {
68
69
70
71
72
73
74
        val printer = CSVPrinter(writer, CSVFormat.DEFAULT.withFirstRecordAsHeader())
        printer.printRecord("Interface", "Seed", "Size", "Best")
        for (record in records) {
            printer.printRecord(record)
        }
        writer.close()
    }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

    companion object {
        /**
         * Static method giving the expected CSV header
         * @return A string for the expected CSV header
         */
        fun getExpectedHeader() : String {
            val header =
                    listOf(
                            "Benchmark",
                            "Mode",
                            "Threads",
                            "Samples",
                            "Score",
                            "Score Error (99.9%)",
                            "Unit",
                            "Param: applicationSize",
                            "Param: baseStructureSize",
                            "Param: datastructureName",
                            "Param: seed"
                    ).map { "\"$it\""}.joinToString(",")
            return header
        }
    }
99
}