Skip to content

Instantly share code, notes, and snippets.

@lrhn
Last active October 5, 2020 09:17
Show Gist options
  • Save lrhn/4a53a91bf4e0006e4af4c8a598b68ee6 to your computer and use it in GitHub Desktop.
Save lrhn/4a53a91bf4e0006e4af4c8a598b68ee6 to your computer and use it in GitHub Desktop.
Compare local function to instance method or static method.
var a = -4;
int logicToGetA() => a;
class A {
final int flag;
A(this.flag);
int foo() {
int a = logicToGetA();
int _bar() => someOtherLogic(a);
int b = _bar();
return b;
}
int someOtherLogic(int a) {
// Should prevent inlining.
if (a < 0) return someOtherLogic(a + 1);
return a + flag;
}
}
class B {
final int flag;
B(this.flag);
int _bar(int a) => someOtherLogic(a);
int foo() {
int a = logicToGetA();
int b = _bar(a);
return b;
}
int someOtherLogic(int a) {
// Should prevent inlining.
if (a < 0) return someOtherLogic(a + 1);
return a + flag;
}
}
class S {
final int flag;
S(this.flag);
int foo() {
int a = logicToGetA();
int _bar() => someOtherLogic(a, this);
int b = _bar();
return b;
}
static int someOtherLogic(int a, S self) {
// Should prevent inlining.
if (a < 0) return someOtherLogic(a + 1, self);
return a + self.flag;
}
}
double benchA(int ms, int flag) {
var a = A(flag);
var count = 0;
var elapsed = 0;
var sw = Stopwatch()..start();
int r = 0;
do {
for (var i = 0; i < 10000; i++) {
r ^= a.foo();
}
elapsed = sw.elapsedMilliseconds;
count += 10000;
} while (elapsed < ms);
if (r != 0) throw "wrong";
return count / elapsed;
}
double benchB(int ms, int flag) {
var a = B(flag);
var count = 0;
var elapsed = 0;
var sw = Stopwatch()..start();
int r = 0;
do {
for (var i = 0; i < 10000; i++) {
r ^= a.foo();
}
elapsed = sw.elapsedMilliseconds;
count += 10000;
} while (elapsed < ms);
if (r != 0) throw "wrong";
return count / elapsed;
}
double benchS(int ms, int flag) {
var a = S(flag);
var count = 0;
var elapsed = 0;
var sw = Stopwatch()..start();
int r = 0;
do {
for (var i = 0; i < 10000; i++) {
r ^= a.foo();
}
elapsed = sw.elapsedMilliseconds;
count += 10000;
} while (elapsed < ms);
if (r != 0) throw "wrong";
return count / elapsed;
}
main(List<String> args) async {
a = args.isEmpty ? 0 : 1; // Make value unpredictable to compiler
// Warmup.
benchA(500, 1);
benchB(500, 1);
benchS(500, 1);
// Run bench three times.
for (var i = 0; i < 3; i++) {
await sleep;
print("A: ${benchA(2000, 0)} /ms");
await sleep;
print("B: ${benchB(2000, 0)} /ms");
await sleep;
print("S: ${benchS(2000, 0)} /ms");
}
}
Future<void> get sleep => Future(() {});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment