在使用Dart语言的32位整数32位机器上工作时,我有点气馁。
这是否意味着Dart VM仍未针对整数运算进行优化?
这是我非常直接的测试。
void main() {
var tests = new List();
tests.add({"name" : "16-bit", "result" : 0});
tests.add({"name" : "32-bit", "result" : 0});
tests[0]["result"] = test1(0x8000);
tests[1]["result"] = test1(0x80000000);
int best;
for(var test in tests) {
var result = test["result"];
if(best == null) {
best = result;
} else if(best > result) {
best = result;
}
}
for(var test in tests) {
var result = test["result"];
var percent = (result / best * 100).round();
print("${test["name"]}: $percent%");
}
}
int test1(int value) {
int result = 0;
var count = 10000000;
var sw = new Stopwatch();
sw.start();
for(var i = 0; i < count; i++) {
var result = value + i;
}
sw.stop();
return sw.elapsedMicroseconds;
}
输出:
16-bit: 100%
32-bit: 13285%
这意味着在某些real
个案例中,性能可能会慢130倍?
答案 0 :(得分:4)
您的测试存在缺陷。 test2
不能使用32位整数,因为数字会变大。
如果您按如下方式修改测试,则会花费同样的时间:
library lexer_perf;
import '_perf.dart';
import 'package:angular/core/parser/lexer.dart';
void main() {
var tests = new List();
tests.add({"name" : "16-bit", "result" : 0});
tests.add({"name" : "32-bit", "result" : 0});
tests[1]["result"] = test1(0x3fffffff); // 2^30 is the maximum small (32bit) integer value
tests[0]["result"] = test1(0xffff);
int best;
for(var test in tests) {
var result = test["result"];
if(best == null) {
best = result;
} else if(best > result) {
best = result;
}
}
for(var test in tests) {
var result = test["result"];
var percent = (result / best * 100).round();
print("${test["name"]}: $percent%");
}
}
int test1(int value) {
int result = 0;
var count = 10000000;
var sw = new Stopwatch();
sw.start();
for(var i = 0; i < count; i++) {
var result = value - i; // Subtract instead of add so that we do not exceed maximum small integer value.
}
sw.stop();
return sw.elapsedMicroseconds;
}
输出:
16-bit: 122% // Well within margin of error.
32-bit: 100%
答案 1 :(得分:1)
原始问题:“是否可以在Dart中编写适用于具有32位整数的32位机器的高性能代码?”
简答:不可以。可以为31位整数编写高性能代码,但不能编写32位整数。
为什么?
Dart没有32位整数的概念。
根据Dart规范,整数是任意长度的。但出于性能原因,较小范围有不同的内部表示。问题是small int
范围不是32位,而是31位(在32位系统上)。因此,[-(2^30+1), -(2^31)]
或[2^30, 2^31-1]
之间的所有内容都不再是small int
,而是medium int
,即64位。
完整范围,为了完整起见,是:
System smi mint bigint
[32bit system]: 31bit 64bit limited by RAM
[64bit system]: 63bit 64bit limited by RAM
来源:https://www.dartlang.org/articles/numeric-computation/#integers