mirror of
https://github.com/dart-lang/sdk
synced 2024-10-01 19:19:16 +00:00
4af8469493
* Added a name-filter to every benchmark. * Addressed lints. * We don't run the legacy copies anymore, so deleted dart2 dirs. Change-Id: I65705749c5c90aad77d1fb93ea4a0d4e8b656cd4 Cq-Include-Trybots: luci.dart.try:benchmark-linux-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301522 Reviewed-by: Jonas Termansen <sortie@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com>
155 lines
4.1 KiB
Dart
155 lines
4.1 KiB
Dart
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// Macro-benchmark for ffi with boringssl.
|
|
|
|
import 'dart:convert';
|
|
import 'dart:ffi';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
|
import 'package:ffi/ffi.dart';
|
|
|
|
import 'digest.dart';
|
|
import 'types.dart';
|
|
|
|
//
|
|
// BoringSSL functions
|
|
//
|
|
|
|
Uint8List inventData(int length) {
|
|
final result = Uint8List(length);
|
|
for (int i = 0; i < length; i++) {
|
|
result[i] = i % 256;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Uint8List toUint8List(Pointer<Bytes> bytes, int length) {
|
|
final result = Uint8List(length);
|
|
final uint8bytes = bytes.asUint8Pointer();
|
|
for (int i = 0; i < length; i++) {
|
|
result[i] = uint8bytes[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void copyFromUint8ListToTarget(Uint8List source, Pointer<Data> target) {
|
|
final int length = source.length;
|
|
final uint8target = target.asUint8Pointer();
|
|
for (int i = 0; i < length; i++) {
|
|
uint8target[i] = source[i];
|
|
}
|
|
}
|
|
|
|
String hash(Pointer<Data> data, int length, Pointer<EVP_MD> hashAlgorithm) {
|
|
final context = EVP_MD_CTX_new();
|
|
EVP_DigestInit(context, hashAlgorithm);
|
|
EVP_DigestUpdate(context, data, length);
|
|
final int resultSize = EVP_MD_CTX_size(context);
|
|
final Pointer<Bytes> result = calloc<Uint8>(resultSize).cast();
|
|
EVP_DigestFinal(context, result, nullptr);
|
|
EVP_MD_CTX_free(context);
|
|
final String hash = base64Encode(toUint8List(result, resultSize));
|
|
calloc.free(result);
|
|
return hash;
|
|
}
|
|
|
|
//
|
|
// Benchmark fixtures.
|
|
//
|
|
|
|
// Number of repeats: 1 && Length in bytes: 10000000
|
|
// * CPU: Intel(R) Xeon(R) Gold 6154
|
|
// * Architecture: x64
|
|
// * 23000 - 52000000 us (without optimizations)
|
|
// * 23000 - 30000 us (with optimizations)
|
|
const int L = 1000; // Length of data in bytes.
|
|
|
|
final hashAlgorithm = EVP_sha512();
|
|
|
|
// Hash of generated data of `L` bytes with `hashAlgorithm`.
|
|
const String expectedHash =
|
|
'bNLtqb+cBZcSkCmwBUuB5DP2uLe0madetwXv10usGUFJg1sdGhTEi+aW5NWIRW1RKiLq56obV74rVurn014Iyw==';
|
|
|
|
/// This benchmark runs a digest algorithm on data residing in C memory.
|
|
///
|
|
/// This benchmark is intended as macro benchmark with a realistic workload.
|
|
class DigestCMemory extends BenchmarkBase {
|
|
DigestCMemory() : super('FfiBoringssl.DigestCMemory');
|
|
|
|
Pointer<Data> data = nullptr; // Data in C memory that we want to digest.
|
|
|
|
@override
|
|
void setup() {
|
|
data = calloc<Uint8>(L).cast();
|
|
copyFromUint8ListToTarget(inventData(L), data);
|
|
hash(data, L, hashAlgorithm);
|
|
}
|
|
|
|
@override
|
|
void teardown() {
|
|
calloc.free(data);
|
|
}
|
|
|
|
@override
|
|
void run() {
|
|
final String result = hash(data, L, hashAlgorithm);
|
|
if (result != expectedHash) {
|
|
throw Exception('$name: Unexpected result: $result');
|
|
}
|
|
}
|
|
}
|
|
|
|
/// This benchmark runs a digest algorithm on data residing in Dart memory.
|
|
///
|
|
/// This benchmark is intended as macro benchmark with a realistic workload.
|
|
class DigestDartMemory extends BenchmarkBase {
|
|
DigestDartMemory() : super('FfiBoringssl.DigestDartMemory');
|
|
|
|
Uint8List data = Uint8List(0); // Data in C memory that we want to digest.
|
|
|
|
@override
|
|
void setup() {
|
|
data = inventData(L);
|
|
final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
|
|
copyFromUint8ListToTarget(data, dataInC);
|
|
hash(dataInC, L, hashAlgorithm);
|
|
calloc.free(dataInC);
|
|
}
|
|
|
|
@override
|
|
void teardown() {}
|
|
|
|
@override
|
|
void run() {
|
|
final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
|
|
copyFromUint8ListToTarget(data, dataInC);
|
|
final String result = hash(dataInC, L, hashAlgorithm);
|
|
calloc.free(dataInC);
|
|
if (result != expectedHash) {
|
|
throw Exception('$name: Unexpected result: $result');
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Main driver.
|
|
//
|
|
|
|
void main(List<String> args) {
|
|
final benchmarks = [
|
|
DigestCMemory.new,
|
|
DigestDartMemory.new,
|
|
];
|
|
|
|
final filter = args.firstOrNull;
|
|
for (var constructor in benchmarks) {
|
|
final benchmark = constructor();
|
|
if (filter == null || benchmark.name.contains(filter)) {
|
|
benchmark.report();
|
|
}
|
|
}
|
|
}
|