Skip to content

Instantly share code, notes, and snippets.

@eernstg
Last active January 30, 2024 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eernstg/17e70499f240b1b45172a14df7f26a8c to your computer and use it in GitHub Desktop.
Save eernstg/17e70499f240b1b45172a14df7f26a8c to your computer and use it in GitHub Desktop.
const count = 1000000;
bool b = false;
dynamic top;
void main() {
var sw = Stopwatch();
sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, 2, 3, ...List<int> myList, 1] when b: top = myList;
case [1, 2, ...List<int> myList, 1] when b: top = myList;
case [1, ...List<int> myList, 1]: top = myList;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, match 4/3/2, create 3');
sw.reset(); sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, 2, 3, ..., 1] when b: break;
case [1, 2, ..., 1] when b: break;
case [1, ...List<int> myList, 1]: top = myList;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, match 4/3/2, create 1');
sw.reset(); sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, 2, 3, ..., 1] when b: break;
case [1, 2, ..., 1] when b: break;
case [1, ..., 1]: break;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, match 4/3/2, create 0');
sw.reset(); sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, ...List<int> myList, 1] when b: top = myList;
case [1, ...List<int> myList, 1] when b: top = myList;
case [1, ...List<int> myList, 1]: top = myList;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, create 1, get 2 from cache');
sw.reset(); sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, ..., 1] when b: break;
case [1, ..., 1] when b: break;
case [1, ...List<int> myList, 1]: top = myList;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, create 1, no cache');
sw.reset(); sw.start();
for (int i = 0; i < count; ++i) {
switch (<int>[1, 2, 3, i, 3, 2, 1]) {
case [1, ..., 1] when b: break;
case [1, ..., 1] when b: break;
case [1, ..., 1]: break;
}
}
sw.stop();
print('Elapsed ${sw.elapsedMicroseconds}, create 0');
}
// Based on chat with Slava about the cost associated with binding rest
// patterns in list patterns: Do they have to create a new list?
//
// Trying out the cost of binding rest patterns in list patterns, do we
// actually cache the results when that would be possible?
//
// Example output from run:
/*
> dart n039.dart
head_test_dart n039.dart
Elapsed 140266, match 4/3/2, create 3
Elapsed 306814, match 4/3/2, create 1
Elapsed 20366, match 4/3/2, create 0
Elapsed 822918, create 1, get 2 from cache
Elapsed 302487, create 1, no cache
Elapsed 18273, create 0
> dart compile exe n039.dart
> ./n039.exe
Elapsed 87765, match 4/3/2, create 3
Elapsed 32439, match 4/3/2, create 1
Elapsed 541, match 4/3/2, create 0
Elapsed 32748, create 1, get 2 from cache
Elapsed 32503, create 1, no cache
Elapsed 812, create 0
> dart compile js n039.dart
> d8 out.js
Elapsed 218000, match 4/3/2, create 3
Elapsed 74000, match 4/3/2, create 1
Elapsed 9000, match 4/3/2, create 0
Elapsed 150000, create 1, get 2 from cache
Elapsed 70000, create 1, no cache
Elapsed 8000, create 0
*/
// Lessons learned from this:
//
// - 'match 4/3/2, create 1', 'create 1, get 2 from cache', 'create 1,
// no cache' are surprisingly expensive on the VM.
// - AOT (exe) seems to work very well.
// - AOT (js) is expensive at 140000, create 1, get 2 from cache.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment