0

I use simple test code in How to improve Dart performance of data conversion to/from binary? (with only difference: const int BufSize = 8388608;) to measure Dart performance in release and debug build and discover weird result: release build is about 12 times slower then debug!

The code was tested in Lollipop Android device.

I expected release build would be few times faster then debug, but everything is exact opposite:

debug:

I/flutter (26195): Conversion(RunTime): 2654529.0 us.

release

I/flutter (26231): Conversion(RunTime): 32347612.0 us.

What is wrong here? Thanks.

Minh Tran
  • 3
  • 1

2 Answers2

0

It is possible for Just-In-Time compilation (debug mode) to work faster than Ahead-Of-Time compilation (release mode). And seems like it's a known issue for Dart.

Igor Kharakhordin
  • 9,185
  • 3
  • 40
  • 39
  • https://github.com/flutter/flutter/issues/19677 this issue was created more then one year ago. One year later it get lots worse, 12 times slower? Seriously? Does it mean that Flutter is not suitable for production? I hope some Google engineers will help to answer this question. Thanks – Minh Tran Nov 04 '19 at 09:31
0

There is an oversight in the optimising compiler which makes it slower than it should be. I have filed an issue to fix it.

The issue is that AOT compiler emits some unnecessary speculative code when inlining ByteData methods for writing 8, 16 and 32-bit integers. If it later can't prove that its speculation holds it ends up generating much worse code. In some sense this is something left over from pre-Dart 2 times.

We are going to fix it in the compiler. However you can also work around it by doing explicit masking on arguments of these methods. For example if you rewrite the core of the benchmark like this

      buffer.setInt32(offset, intContent & 0xFFFFFFFF); offset += 4; intContent++;
      buffer.setInt32(offset, intContent & 0xFFFFFFFF); offset += 4; intContent++;
      buffer.setInt16(offset, intContent & 0xFFFF); offset += 2; intContent++;
      buffer.setInt16(offset, intContent & 0xFFFF); offset += 2; intContent++;
      buffer.setInt8(offset, intContent & 0xFF); offset += 1; intContent++;
      buffer.setInt8(offset, intContent & 0xFF); offset += 1; intContent++;

It should significantly improve the performance of the benchmark. Though there would still be some difference between release and debug mode (2-3x) because there are still optimisation opportunities in the generated AOT code.

Vyacheslav Egorov
  • 10,302
  • 2
  • 43
  • 45
  • Thank you. I hope you can fix this issue to make Flutter better. For now I have workaround by minimizing writing in Dart in my app. Reading seems to be fast, I see no problems with reading. Regarding typed_data, I think there is definitely bug: Uint8List (and similar lists) allow writing, e.g. theUint8List[2] = 123;, but it ends up damaging Uint8List after a while. How I can modify Uint8List without Uint8List corruption? Thanks – Minh Tran Nov 06 '19 at 04:11
  • I understand that buffer.setInt8() might be fine (just slow), but assigning theUint8List[2] = 123 will eventually damage the list. Pls create an issue if this is a bug. Thanks – Minh Tran Nov 06 '19 at 04:28
  • I am not sure I understand what “damaging the list” means. Do you have an example - can you post some code that demonstrates the problem? – Vyacheslav Egorov Nov 06 '19 at 06:56
  • I cannot longer re-produce the issue with list corruption, probably it was problem with debugger/ hot reload, not with Dart Uint8List itself. Thank you. – Minh Tran Nov 07 '19 at 01:04