注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

韩国恺的博客

hanguokai.com

 
 
 

日志

 
 

Dart 性能测试  

2013-03-01 20:46:56|  分类: Dart |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
我们通常需要对代码或核心算法做性能测试。性能测试的概念非常简单:执行要测试的代码,测量其执行时间(一般是多次测试的平均值)。性能测试真正的难点是避开各种干扰因素,而这些干扰因素可能非常复杂。除了自身代码,还可能涉及硬件、底层系统、语言、库的实现等各个方面。Dart 中的性能测试和其它语言并没有什么不同,只不过需要注意几点。

1. 热身
Dart 语言的一个目标是快速启动,为此 Dart VM 并不会立刻优化要执行的代码。执行时间太短、次数太少的代码无法触发 VM 的优化器,这样的结果并不能反映真实的性能数据。所以,在正式开始记录执行时间之前要预先执行足够多的次数和时间,然后再开始测试性能。

除了热身,测试本身也要执行足够的时间和次数才能获得准确的数据,尤其是单次执行时间很短的测试。

2. 关闭检查模式和调试模式
Dart 有两种执行模式:检查模式(checked)和生产模式(production)。检查模式会在运行时插入大量类型检查,自然会影响性能。命令行模式下 dart 默认就是生产模式。但在 Dart Editor 中默认是在检查模式下运行,首先保证程序在检查模式下执行没问题,然后在性能测试时在程序的启动配置中取消 VM 的 “Run in checked mode”选项。

此外,debug 模式也会对性能有影响。在 Dart Editor 的选项配置中,Run and Debug 中的 break on exceptions 设为 none 。

基本性能测试代码
假设要执行的测试函数 func() ,那么代码大概是像下面这样:

int m = 10, n = 100;
//预先执行 m 次调用作为热身,但不计时间
for(int i = 0; i < m; i++){
func();
}
 

//开始计时,并执行 n 次调用
var st = new Stopwatch()..start();

for(int i = 0; i < n; i++){
func();
}
 

//打印测试结果
print("Runtime is ${sw.elapsedMicroseconds/n} us");

在 Dart 中 Stopwatch 用于计时,Stopwatch 对象有两个属性表示启动之后逝去的时间:elapsedMilliseconds(逝去的毫秒) 和 elapsedMicroseconds(逝去的微妙,即千分之一毫秒)。以上代码用的是微妙,也可以用毫秒。

相应的 JavaScript 代码也类似,只是用 (new Date).getTime() 获得时间(单位是毫秒)。用 console.time() 和 console.timeEnd() 更方便。

var m = 10, n = 100;

for(var i = 0; i < m; i++){
func();
}

var start = (new Date).getTime(); //或 console.time();

for(var i = 0; i < n; i++){
func();
}

var time = ((new Date).getTime() - start)/n; //或 console.timeEnd();


为了保证代码被执行足够的时间(比如1s以上),需要适当调整 m 和 n 的值。还有一个更通用的方法可以保证代码至少执行给定的时间:

double measureFor(Function f, int timeMinimum) {
int time = 0;
int iter = 0;
Stopwatch watch = new Stopwatch();
watch.start();
int elapsed = 0;
while (elapsed < timeMinimum) {
f();
elapsed = watch.elapsedMilliseconds;
iter++;
}
return 1000.0 * elapsed / iter;
}

上面这个函数摘自 benchmark_harness 库,f 是要执行的测试,timeMinimum 是执行的最少时间(毫秒),返回每次执行的微秒。

利用 benchmark_harness 进行测试
Dart 提供了 benchmark_harness 库用于性能测试,这个库的实现非常简单,就是在干我们前面说的那些事。

在 pubspec.yaml 中添加:

dependencies:
benchmark_harness: any

执行 pub install,然后导入:

import 'package:benchmark_harness/benchmark_harness.dart';

使用时可以 copy 提供的代码模版,其中 run 是要执行的测试:

// Import BenchmarkBase class.
import 'package:benchmark_harness/benchmark_harness.dart';

// Create a new benchmark by extending BenchmarkBase
class TemplateBenchmark extends BenchmarkBase {
const TemplateBenchmark() : super("Template");

static void main() {
new TemplateBenchmark().report();
}

// The benchmark code.
void run() {
}

// Not measured setup code executed prior to the benchmark runs.
void setup() { }

// Not measures teardown code executed after the benchark runs.
void teardown() { }
}

main() {
// Run TemplateBenchmark
TemplateBenchmark.main();
}

这里继承了 BenchmarkBase ,然后覆盖 run 方法,最后调用 report 方法执行。
注意输出的结果是以10次测试为单位的平均值(而非一次测试的结果)。


参考资料:
  评论这张
 
阅读(2152)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018