dart_style icon indicating copy to clipboard operation
dart_style copied to clipboard

Slow formatting with named arguments

Open dcharkes opened this issue 4 years ago • 1 comments
trafficstars

I apologize for torturing the formatter with large generated files. 🙈

The formatter seems to be much slower on files with named arguments.

Consider the following two files:

  • https://github.com/dart-lang/sdk/blob/main/tests/ffi/function_structs_by_value_generated_test.dart
  • https://github.com/dart-lang/sdk/blob/main/tests/ffi/function_structs_by_value_generated_leaf_test.dart

They are nearly identical, apart from , isLeaf: true as extra argument.

Formatted /usr/local/google/home/dacoharkes/dart-sdk/sdk/tests/ffi/function_structs_by_value_generated_test.dart
Formatted 1 file (1 changed) in 2.74 seconds.
Formatted /usr/local/google/home/dacoharkes/dart-sdk/sdk/tests/ffi/function_structs_by_value_generated_leaf_test.dart
Formatted 1 file (1 changed) in 6.71 seconds.

One line repro on dart-sdk HEAD:

dart tests/ffi/generator/structs_by_value_tests_generator.dart

dcharkes avatar Oct 14 '21 16:10 dcharkes

Yeah, generated code tends to hit all of the worst-case performance corners of the formatter.

munificent avatar Oct 15 '21 23:10 munificent

Hey, Daco. I believe the new formatter should have much better performance, but I'd like to write a regression test to verify that. It looks like the slow files have been reorganized since this issue was filed. Can you point me to any chunks of code in the generated FFI tests that are slow to format with the old formatter?

munificent avatar Aug 02 '24 20:08 munificent

These are the tree biggest ones:

  • https://github.com/dart-lang/sdk/blob/main/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
  • https://github.com/dart-lang/sdk/blob/main/tests/ffi/function_structs_by_value_generated_args_leaf_test.dart
  • https://github.com/dart-lang/sdk/blob/main/tests/ffi/function_structs_by_value_generated_args_native_leaf_test.dart

dcharkes avatar Aug 05 '24 07:08 dcharkes

I dug into it and the piece of code that causes most of the formatter slowdown is:

final passInt32x8Doublex8Int64Int8Struct1ByteIntInt64IntLeaf =
    ffiTestFunctions.lookupFunction<
        Double Function(
            Int32,
            Int32,
            Int32,
            Int32,
            Int32,
            Int32,
            Int32,
            Int32,
            Double,
            Double,
            Double,
            Double,
            Double,
            Double,
            Double,
            Double,
            Int64,
            Int8,
            Struct1ByteInt,
            Int64,
            Int8,
            Struct4BytesHomogeneousInt16,
            Int64,
            Int8,
            Struct8BytesInt,
            Int64,
            Int8,
            Struct8BytesHomogeneousFloat,
            Int64,
            Int8,
            Struct8BytesMixed,
            Int64,
            Int8,
            StructAlignmentInt16,
            Int64,
            Int8,
            StructAlignmentInt32,
            Int64,
            Int8,
            StructAlignmentInt64),
        double Function(
            int,
            int,
            int,
            int,
            int,
            int,
            int,
            int,
            double,
            double,
            double,
            double,
            double,
            double,
            double,
            double,
            int,
            int,
            Struct1ByteInt,
            int,
            int,
            Struct4BytesHomogeneousInt16,
            int,
            int,
            Struct8BytesInt,
            int,
            int,
            Struct8BytesHomogeneousFloat,
            int,
            int,
            Struct8BytesMixed,
            int,
            int,
            StructAlignmentInt16,
            int,
            int,
            StructAlignmentInt32,
            int,
            int,
            StructAlignmentInt64)>("PassInt32x8Doublex8Int64Int8Struct1ByteIntInt64Int", isLeaf: true);

The old formatter takes about 650ms to format that on my laptop. The new formatter formats it in 0.168ms, about 3000x faster. So that's good. :)

The overall formatting times for those three files on my laptop are:

Old formatter:
0:00:01.262616: ffi/function_structs_by_value_generated_args_leaf_test.dart
0:00:00.314476: ffi/function_callbacks_structs_by_value_generated_test.dart
0:00:00.051217: ffi/function_structs_by_value_generated_args_native_leaf_test.dart

New formatter:
0:00:00.110299: ffi/function_structs_by_value_generated_args_leaf_test.dart
0:00:00.292947: ffi/function_callbacks_structs_by_value_generated_test.dart
0:00:00.050187: ffi/function_structs_by_value_generated_args_native_leaf_test.dart
...1 more file each took less than 10ms.

So that one hot spot is fixed and everything else seems basically OK to me. Those formatting times are fairly large but I think it's mostly because the files are quite large.

I added a benchmark to capture this corner of the language so that we know not to regress it. Thanks for filing the issue!

munificent avatar Aug 06 '24 20:08 munificent

Awesome! Thanks @munificent! ❤️

dcharkes avatar Aug 07 '24 07:08 dcharkes