Skip to content

Commit bd1e20e

Browse files
authored
Allow perf harness to compare multiple revisions of SwiftProtobuf (apple#426)
* Separate perf harness generator and runner scripts. * Update perf harness to compare revisions. * Remove commented code; add checkout cleanup hook.
1 parent fc68a01 commit bd1e20e

File tree

7 files changed

+308
-157
lines changed

7 files changed

+308
-157
lines changed

Performance/css/harness-visualization.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ table.numeric td {
1616

1717
table.numeric th {
1818
background-color: #eee;
19-
text-align: right;
19+
text-align: center;
2020
}
2121

2222
table.numeric tfoot td {

Performance/perf_runner_cpp.sh renamed to Performance/generators/cpp.sh

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# SwiftProtobuf/Performance/perf_runner_cpp.sh - C++ test harness generator
3+
# SwiftProtobuf/Performance/generators/cpp.sh - C++ test harness generator
44
#
55
# This source file is part of the Swift.org open source project
66
#
@@ -16,8 +16,6 @@
1616
#
1717
# -----------------------------------------------------------------------------
1818

19-
set -eu
20-
2119
function print_cpp_set_field() {
2220
num=$1
2321
type=$2
@@ -157,32 +155,3 @@ EOF
157155
}
158156
EOF
159157
}
160-
161-
function run_cpp_harness() {
162-
harness="$1"
163-
164-
echo "Generating C++ harness source..."
165-
gen_harness_path="$script_dir/_generated/Harness+Generated.cc"
166-
generate_cpp_harness "$field_count" "$field_type"
167-
168-
echo "Building C++ test harness..."
169-
time ( g++ --std=c++11 -O \
170-
-o "$harness" \
171-
-I "$script_dir" \
172-
-I "$GOOGLE_PROTOBUF_CHECKOUT/src" \
173-
-L "$GOOGLE_PROTOBUF_CHECKOUT/src/.libs" \
174-
-lprotobuf \
175-
"$gen_harness_path" \
176-
"$script_dir/Harness.cc" \
177-
"$script_dir/_generated/message.pb.cc" \
178-
"$script_dir/main.cc" \
179-
)
180-
echo
181-
182-
# Make sure the dylib is loadable from the harness if the user hasn't
183-
# actually installed them.
184-
cp "$GOOGLE_PROTOBUF_CHECKOUT"/src/.libs/libprotobuf.*.dylib \
185-
"$script_dir/_generated"
186-
187-
run_harness_and_concatenate_results "C++" "$harness" "$partial_results"
188-
}

Performance/perf_runner_swift.sh renamed to Performance/generators/swift.sh

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# SwiftProtobuf/Performance/perf_runner_swift.sh - Swift test harness generator
3+
# SwiftProtobuf/Performance/generators/swift.sh - Swift test harness generator
44
#
55
# This source file is part of the Swift.org open source project
66
#
@@ -16,8 +16,6 @@
1616
#
1717
# -----------------------------------------------------------------------------
1818

19-
set -eu
20-
2119
function print_swift_set_field() {
2220
num=$1
2321
type=$2
@@ -86,8 +84,8 @@ extension Harness {
8684
}
8785
8886
// Exercise text serialization.
89-
let text = try measureSubtask("Encode text") {
90-
return try message.textFormatString()
87+
let text = measureSubtask("Encode text") {
88+
return message.textFormatString()
9189
}
9290
_ = try measureSubtask("Decode text") {
9391
return try PerfMessage(textFormatString: text)
@@ -114,41 +112,3 @@ EOF
114112
}
115113
EOF
116114
}
117-
118-
function run_swift_harness() {
119-
harness="$1"
120-
121-
echo "Generating Swift harness source..."
122-
gen_harness_path="$script_dir/_generated/Harness+Generated.swift"
123-
generate_swift_harness "$field_count" "$field_type"
124-
125-
# Build the dynamic library to use in the tests from the .o files that were
126-
# already built for the plug-in.
127-
echo "Building SwiftProtobuf dynamic library..."
128-
swiftc -emit-library -O -wmo -target x86_64-apple-macosx10.10 \
129-
-o "$script_dir/_generated/libSwiftProtobuf.dylib" \
130-
"$script_dir/../Sources/SwiftProtobuf/"*.swift
131-
132-
echo "Building Swift test harness..."
133-
time ( swiftc -O -target x86_64-apple-macosx10.10 \
134-
-o "$harness" \
135-
-I "$script_dir/../.build/release" \
136-
-L "$script_dir/_generated" \
137-
-lSwiftProtobuf \
138-
"$gen_harness_path" \
139-
"$script_dir/Harness.swift" \
140-
"$script_dir/_generated/message.pb.swift" \
141-
"$script_dir/main.swift"
142-
)
143-
echo
144-
145-
dylib="$script_dir/_generated/libSwiftProtobuf.dylib"
146-
echo "Swift dylib size before stripping: $(stat -f "%z" "$dylib") bytes"
147-
cp "$dylib" "${dylib}_stripped"
148-
strip -u -r "${dylib}_stripped"
149-
echo "Swift dylib size after stripping: $(stat -f "%z" "${dylib}_stripped") bytes"
150-
echo
151-
152-
run_harness_and_concatenate_results "Swift" "$harness_swift" "$partial_results"
153-
profile_harness "Swift" "$harness_swift"
154-
}

Performance/js/harness-visualization.js

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
'Equality',
1010
];
1111

12-
// The languages we have harnesses for. The results for each language will
13-
// appear as a series in the plot.
14-
var languages = ['Swift', 'C++'];
15-
1612
// The harnessSize keys we want to print in the summary table, in the order
1713
// they should be displayed.
1814
var harnessSizeKeys = ['Unstripped', 'Stripped'];
@@ -50,7 +46,7 @@
5046
};
5147

5248
// Creates and return a series for the given language's results in a session.
53-
function createSeries(session, language) {
49+
function createSeries(session, series) {
5450
var x = [];
5551
var y = [];
5652

@@ -59,7 +55,7 @@
5955
// vertical, which is what we want.
6056
for (var i = 0; i < benchmarks.length; i++) {
6157
var benchmark = benchmarks[i];
62-
var timings = session[language][benchmark];
58+
var timings = series.data[benchmark];
6359
if (timings) {
6460
for (var j = 0; j < timings.length; j++) {
6561
x.push(benchmark.replace(" ", "<br>"));
@@ -69,7 +65,7 @@
6965
}
7066

7167
return {
72-
name: language,
68+
name: series.name,
7369
x: x,
7470
y: y,
7571
type: 'box',
@@ -126,10 +122,8 @@
126122
// Insert the runtime stats.
127123
var header = $('<tr></tr>').appendTo(table);
128124
header.append($('<th>Median runtimes</th>'));
129-
for (var j = 0; j < languages.length; j++) {
130-
header.append($('<th></th>').text(languages[j]));
131-
header.append($('<th></th>'));
132-
header.append($('<th></th>'));
125+
for (var j = 0; j < session.series.length; j++) {
126+
header.append($('<th colspan="2"></th>').text(session.series[j].name));
133127
}
134128

135129
for (var i = 0; i < benchmarks.length; i++) {
@@ -142,9 +136,8 @@
142136
// Track which language was the fastest
143137
var timings = [];
144138
var bestLanguage = 0;
145-
for (var j = 0; j < languages.length; j++) {
146-
var language = languages[j];
147-
var languageTimings = session[language][benchmark];
139+
for (var j = 0; j < session.series.length; j++) {
140+
var languageTimings = session.series[j].data[benchmark];
148141
if (languageTimings) {
149142
var med = median(languageTimings);
150143
timings.push(med);
@@ -156,8 +149,7 @@
156149

157150
// Insert the per-language timings into the table
158151
var bestValue = timings[bestLanguage];
159-
for (var j = 0; j < languages.length; j++) {
160-
var language = languages[j];
152+
for (var j = 0; j < session.series.length; j++) {
161153
var med = timings[j];
162154
var valueCell = $('<td></td>').appendTo(tr);
163155
var multiplierCell = $('<td></td>').appendTo(tr);
@@ -171,15 +163,13 @@
171163
}
172164
decorateMultiplierCell(multiplierCell, multiplier);
173165
}
174-
tr.append($('<td></td>'));
175166
}
176167
}
177168

178169
// Insert the binary size stats.
179170
header = $('<tr></tr>').appendTo(table);
180171
header.append($('<th>Harness size</th>'));
181-
for (var j = 0; j < languages.length; j++) {
182-
header.append($('<th></th>'));
172+
for (var j = 0; j < session.series.length; j++) {
183173
header.append($('<th></th>'));
184174
header.append($('<th></th>'));
185175
}
@@ -192,16 +182,15 @@
192182

193183
var bestLanguage = 0;
194184
var sizes = [];
195-
for (var j = 0; j < languages.length; j++) {
196-
var language = languages[j];
197-
var size = session[language].harnessSize[harnessSizeKey];
185+
for (var j = 0; j < session.series.length; j++) {
186+
var size = session.series[j].data.harnessSize[harnessSizeKey];
198187
sizes.push(size);
199188
if (size < sizes[bestLanguage]) {
200189
bestLanguage = j;
201190
}
202191
}
203192

204-
for (var j = 0; j < languages.length; j++) {
193+
for (var j = 0; j < session.series.length; j++) {
205194
var size = sizes[j];
206195
var multiplier = size / sizes[bestLanguage];
207196
var formattedSize = size.toLocaleString() + '&nbsp;b';
@@ -213,13 +202,12 @@
213202
multiplierCell.text('(' + multiplier.toFixed(1) + 'x)');
214203
}
215204
decorateMultiplierCell(multiplierCell, multiplier);
216-
tr.append($('<td></td>'));
217205
}
218206
}
219207

220208
var tfoot = $('<tfoot></tfoot>').appendTo(table);
221209
var footerRow = $('<tr></tr>').appendTo(tfoot);
222-
var colspan = 3 * languages.length + 1;
210+
var colspan = 3 * session.series.length + 1;
223211
var footerCell =
224212
$('<td colspan="' + colspan + '"></td>').appendTo(footerRow);
225213
footerCell.text('Green highlights the best result for each test. ' +
@@ -247,21 +235,21 @@
247235
var title = session.type;
248236
var header = $('<h3></h3>').addClass('row').text(title);
249237

250-
var subtitle = 'Branch <tt>' + session.branch +
251-
'</tt>, commit <tt>' + session.commit + '</tt>';
238+
var subtitle = 'Working tree was at <tt>' + session.branch +
239+
'</tt>, commit <tt>' + session.commit.substr(0, 6) + '</tt>';
252240
if (session.uncommitted_changes) {
253241
subtitle += ' (with uncommited changes)';
254242
}
255-
subtitle += ', run on ' + formattedDate;
243+
subtitle += ' &ndash; ' + formattedDate;
256244

257245
header.append($('<small></small>').html(subtitle));
258246
$('#container').append('<hr>');
259247
$('#container').append(header);
260248

261249
var id = 'chart' + i;
262250
var row = $('<div></div>').addClass('row');
263-
var chartColumn = $('<div></div>').addClass('col-md-9');
264-
var tableColumn = $('<div></div>').addClass('col-md-3');
251+
var chartColumn = $('<div></div>').addClass('col-md-8');
252+
var tableColumn = $('<div></div>').addClass('col-md-4');
265253

266254
row.append(chartColumn);
267255
row.append(tableColumn);
@@ -270,12 +258,9 @@
270258
var chart = $('<div></div>').attr('id', id).addClass('chart');
271259
chartColumn.append(chart);
272260

273-
for (var j = 0; j < languages.length; j++) {
274-
var language = languages[j];
275-
if (session[language]) {
276-
var series = createSeries(session, language);
277-
allSeries.push(series);
278-
}
261+
for (var j = 0; j < session.series.length; j++) {
262+
var series = createSeries(session, session.series[j]);
263+
allSeries.push(series);
279264
}
280265

281266
Plotly.newPlot(id, allSeries, layout, {

0 commit comments

Comments
 (0)