【问题标题】:Flutter is faster in debug-mode than when releasedFlutter 在调试模式下比发布时更快
【发布时间】:2021-04-05 14:03:59
【问题描述】:

已解决!查看 julemand101 的 cmets!

我正在测试颤振并遇到了一个小“问题”。该应用程序在调试模式下执行指令的速度似乎比发布时快得多,我想知道这是为什么。

当我使用“flutter run”运行应用程序时,这些是使用冒泡排序对 10 000、25 000 和 50 000 个整数进行排序所需的时间(以毫秒为单位): Debug Mode Times

当我使用“flutter run --release”运行应用程序时,排序时间越来越差,见图: Released App

我刚开始学习 Flutter,所以我保证很多东西都会低于标准,但这里是我使用的代码:

import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String results = "";

  void _runTests() {
    results = "";
       
    var arr = loadArray(10000);
    Stopwatch stopwatch = new Stopwatch()..start();
    bubbleSort(arr);
    timeTaken = stopwatch.elapsedMilliseconds;
    String bubble10k = "Bubble Sort 10k: $timeTaken \n";

    arr = loadArray(25000);
    stopwatch = new Stopwatch()..start();
    bubbleSort(arr);
    timeTaken = stopwatch.elapsedMilliseconds;
    String bubble25k = "Bubble Sort 25k: $timeTaken \n";

    arr = loadArray(50000);
    stopwatch = new Stopwatch()..start();
    bubbleSort(arr);
    timeTaken = stopwatch.elapsedMilliseconds;
    String bubble50k = "Bubble Sort 50k: $timeTaken \n";

     
    setState(() {
      results += 
          bubble10k +
          bubble25k +
          bubble50;
    });
  }

  loadArray(n) {
    var arr = [];
    var rand = new Random();
    while (arr.length < n) {
      var r = rand.nextInt(1000000);
      arr.add(r);
    }
    return arr;
  }

  bubbleSort(var array) {
    int lengthOfArray = array.length;
    for (int i = 0; i < lengthOfArray - 1; i++) {
      for (int j = 0; j < lengthOfArray - i - 1; j++) {
        if (array[j] > array[j + 1]) {
          // Swapping using temporary variable
          int temp = array[j];
          array[j] = array[j + 1];
          array[j + 1] = temp;
        }
      }
    }
    return (array);
  }

  insertionSort(var arr) {
    int n = arr.length;
    for (int i = 1; i < n; ++i) {
      int key = arr[i];
      int j = i - 1;

      while (j >= 0 && arr[j] > key) {
        arr[j + 1] = arr[j];
        j = j - 1;
      }
      arr[j + 1] = key;
    }
    return arr;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Results: ',
            ),
            Text(
              '$results',
              style: TextStyle(fontSize: 25),
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _runTests,
        tooltip: 'Start',
        child: Icon(Icons.add),
      ),
    );
  }
}

谁能解释这是为什么,或者我做错了什么?提前致谢。

【问题讨论】:

  • 你能提供你写的代码吗?此外,flutter run 不是“调试模式”,而是使用即时 (JIT) 编译器运行应用程序,这在某些情况下实际上可以更快(因为它可以根据代码和运行时进行优化)但确实在它“热身”之前需要一些时间。 “发布”将使用 Ahead-Of-Time (AOT) 编译来编译应用程序,其中优化完全基于代码而不是运行时。
  • @julemand101 感谢您的回复。我现在已经用我正在使用的代码更新了问题。有没有办法通过 AOT 编译实现相同的“效率”,或者这根本不可能?
  • 您可以开始帮助编译器,让您的代码更安全。现在,有很多dynamic 打字。此外,将您的代码移植到 nullsafety 以使其更加类型安全。
  • 会这样做!再次感谢:)

标签: android performance flutter kotlin dart


【解决方案1】:

以下只是我添加静态类型后获得的基准性能示例。代码兼容 Dart 2.12

我应该补充一点,我需要重写代码,以便我可以在 Flutter 框架之外运行它,因为我没有使用 Flutter。但结果应该差不多:

import 'dart:math';

void main() {
  var arr = loadArray(10000);
  Stopwatch stopwatch = Stopwatch()..start();
  bubbleSort(arr);
  var timeTaken = stopwatch.elapsedMilliseconds;
  print("Bubble Sort ${arr.length}: $timeTaken");

  arr = loadArray(25000);
  stopwatch = Stopwatch()..start();
  bubbleSort(arr);
  timeTaken = stopwatch.elapsedMilliseconds;
  print("Bubble Sort ${arr.length}: $timeTaken");

  arr = loadArray(50000);
  stopwatch = Stopwatch()..start();
  bubbleSort(arr);
  timeTaken = stopwatch.elapsedMilliseconds;
  print("Bubble Sort ${arr.length}: $timeTaken");
}

final _random = Random();

List<int> loadArray(int n) => List.generate(n, (_) => _random.nextInt(1000000));

List<int> bubbleSort(List<int> array) {
  final lengthOfArray = array.length;

  for (int i = 0; i < lengthOfArray - 1; i++) {
    for (int j = 0; j < lengthOfArray - i - 1; j++) {
      if (array[j] > array[j + 1]) {
        // Swapping using temporary variable
        final temp = array[j];
        array[j] = array[j + 1];
        array[j + 1] = temp;
      }
    }
  }

  return array;
}

List<int> insertionSort(List<int> arr) {
  final n = arr.length;

  for (int i = 1; i < n; ++i) {
    final key = arr[i];
    var j = i - 1;

    while (j >= 0 && arr[j] > key) {
      arr[j + 1] = arr[j];
      j = j - 1;
    }
    arr[j + 1] = key;
  }

  return arr;
}

使用dart run (JIT) 时的输出:

>dart run stackoverflow.dart
Bubble Sort 10000: 172
Bubble Sort 25000: 1201
Bubble Sort 50000: 4420

运行dart compile exe (AOT) 创建的可执行文件时的输出:

>dart compile exe stackoverflow.dart
Info: Compiling with sound null safety
Generated: stackoverflow.exe

>stackoverflow.exe
Bubble Sort 10000: 231
Bubble Sort 25000: 1597
Bubble Sort 50000: 5885

应该注意的是,这种基准测试有点毫无意义,因为它们并没有真正讲述性能的全部故事。例如。 JIT 可以启动较慢,但在多次使用方法时会在一段时间后获得一些速度。

此外,如果您需要对其进行排序,请在您的List 上使用sort() 方法,因为这样会更快;)

JIT: List.sort 50000: 26
AOT: List.sort 50000: 19

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 2021-02-08
    • 2013-06-22
    • 2011-09-02
    • 2010-11-17
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多