如何优化大量使用 if 语句的 Dart 代码?

问题描述 投票:0回答:3

我是 Dart 编程语言的新手,我转向我常用的测试 FizzBuzz 来检查该语言。目前,我有这个相对

if
重的示例,速度相当慢。在我的 MacBook Pro 上,只要删除一个 if 语句,执行时间就会从 36 秒缩短到 25 秒,循环次数为 5000000 次。我想知道如何进一步优化它。

void main() {
  for (int i = 0; i < 5000000; i++) {
    var num = i + 1;
    if (num % 15 == 0) {
      print('FizzBuzz');
      continue;
    }
    if (num % 5 == 0) {
      print('Buzz');
      continue;
    }
    if (num % 3 == 0) {
      print('Fizz');
      continue;
    }
    print(num);
  }
}

我尝试将其全部包装在

switch
语句中,如下所示,但它没有编译为JS,并且DartPad给出错误
Type 'int' of the switch expression isn't assignable to the type 'bool' of case expressions.

void main() {
  for (int i = 0; i < 5000000; i++) {
    var num = i + 1;
    switch (num) {
      case (num % 15 == 0):
        print('FizzBuzz');
        break;
      case (num % 5 == 0):
        print('Buzz');
        break;
      case (num % 3 == 0):
        print('Fizz');
        break;
      default:
        print(num);
    }
  }
}

提前谢谢您。

optimization dart
3个回答
0
投票

num
是内置类型的类型(
int
double
的共同超类型),而且
case ...:
表达式需要是常量,因此不能基于非常量值进行计算。

我认为使用

if
是最好的选择。


0
投票

在进行这样的性能测试时,打印到控制台变得非常重要。使用您的代码,您最重要的是在这里测试打印速度。条件语句和增量只是运行时间的一小部分。

尝试以下操作:

import 'dart:async';

main(){
  // mark the start of go
  var begin = DateTime.now();
  go();
  //mark the time that go completes and goZoned begins
  var midpoint = DateTime.now();
  goZoned();
  // mark the end of goZoned
  var end = DateTime.now();
  print("done:\n$begin\n$midpoint\n$end");
}

// This function runs the go function, but short-circuits any calls to print
// with a no-op
void goZoned() {
  runZoned(() {
    go();
  }, zoneSpecification: new ZoneSpecification(
      print: (Zone self, ZoneDelegate parent, Zone zone, String line) {}
      )
  );
}

void go(){
    for (int i = 0; i < 5000000; i++) {
      var num = i + 1;
      if (num % 15 == 0) {
        print('FizzBuzz');
        continue;
      }
      if (num % 5 == 0) {
        print('Buzz');
        continue;
      }
      if (num % 3 == 0) {
        print('Fizz');
        continue;
      }
      print(num);
    }
}

我机器上的结果是

done:
2018-09-10 10:33:23.012086
2018-09-10 10:33:33.407191
2018-09-10 10:33:33.827196

您可以看到,有 print 语句的执行花费了 10 多秒,但没有 print 语句的执行时间略多于三分之一秒。

(挂墙时间仍然是一种非常粗略的测量运行时间的方法,但在这里可以发挥作用)


0
投票

FizzBuzz 可以在不使用 if 语句的情况下解决:

void main() {
  fizzBuzz(100).forEach(print);
}

Iterable<String> fizzBuzz(int limit) sync* {
  for (int i = 1; i <= limit; i++) {
    yield i % 3 == 0 && i % 5 == 0
        ? "FizzBuzz"
        : i % 3 == 0
            ? "Fizz"
            : i % 5 == 0
                ? "Buzz"
                : i.toString();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.