Skip to content

[frontend] IIFEs could be made cheaper? #52694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
modulovalue opened this issue Jun 13, 2023 · 4 comments
Open

[frontend] IIFEs could be made cheaper? #52694

modulovalue opened this issue Jun 13, 2023 · 4 comments
Labels
cfe-encodings Encoding related CFE issues. legacy-area-front-end Legacy: Use area-dart-model instead.

Comments

@modulovalue
Copy link
Contributor

This issue contains a small benchmark that attempts to show that the performance of IIFEs could be improved.

In short, It looks like IIFEs are not being converted to Kernel BlockExpressions (which have no equivalent on the Dart level), and it looks like they could be converted to BlockExpressions as an optimization.

Consider the following:

void main() {
  const iterations = 1000000;
  for (int i = 0; i < 20; i++) {
    print("=" * 80);
    measure(
      fn: () {
        int total = 0;
        for (int i = 0; i < iterations; i++) {
          {
            total += i;
          }
        }
        print(" - total: " + total.toString());
      },
      name: "   => in a block statement",
    );
    measure(
      fn: () {
        int total = 0;
        for (int i = 0; i < iterations; i++) {
          (){
            total += id_fn(i);
          }();
        }
        print(" - total: " + total.toString());
      },
      name: "   => in an IIFE",
    );
    print("=" * 80);
  }
}

int id_fn(
  final int i,
) =>
    i;

void measure({
  required final void Function() fn,
  required final String name,
}) {
  final s = Stopwatch();
  s.start();
  fn();
  s.stop();
  print(
    name + " took: " + (s.elapsedMicroseconds / 1000).toString() + "ms",
  );
}

AOT:

 - total: 499999500000
   => in a block statement took: 0.48ms
 - total: 499999500000
   => in an IIFE took: 4.417ms

JIT:

 - total: 499999500000
   => in a block statement took: 0.52ms
 - total: 499999500000
   => in an IIFE took: 1.59ms

IIFEs are useful for keeping code close to where it is being used which reduces the effort needed to reason about code. I think that making IIFEs cheaper would be great.

@lrhn lrhn added the legacy-area-front-end Legacy: Use area-dart-model instead. label Jun 13, 2023
@ds84182
Copy link
Contributor

ds84182 commented Jun 14, 2023

I don't actually understand why you'd want an IIFE there (or at all). To me it doesn't seem to provide anything of value as blocks are also close to where its used.

@modulovalue
Copy link
Contributor Author

modulovalue commented Jun 14, 2023

The code that I've provided in the issue description is only meant to demonstrate the difference in performance.

This dart-lang/site-www#4613 issue contains more about the why aspect of IIFEs.

Edit: In short, IIFEs are expressions and can be used to "localize" lists of statements where only expressions are being expected.

@johnniwinther
Copy link
Member

cc @jensjoha @alexmarkov

@jensjoha
Copy link
Contributor

jensjoha commented Jun 14, 2023

Isn't this more the VM that should inline it but apparently doesn't?
Or maybe, looking at the flowgraph, inlines, but still keeps all the closure stuff, e.g.:

 28:     v19 <- AllocateUninitializedContext:42(num_variables=1) T{Context}
 30:     StoreField(v19 . i = v5 T{_Smi}, NoStoreBarrier)
 32:     StoreField(v19 . Context.parent = v30 T{Context?}, NoStoreBarrier)
 34:     v22 <- BinarySmiOp:32(+ [-o], v5 T{_Smi}, v21) [-4611686018427387903, 1000000] T{_Smi}
 36:     StoreField(v19 . i = v22, NoStoreBarrier)
 38:     ParallelMove rcx <- rax goto:48 B5

though I might be reading it wrong.

/cc @mraleph

(this was on this modified code btw:

        for (int i = 0; i < iterations; i++) {
          (){
            total += i;
          }();
        }

)

@johnniwinther johnniwinther added the cfe-encodings Encoding related CFE issues. label Oct 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cfe-encodings Encoding related CFE issues. legacy-area-front-end Legacy: Use area-dart-model instead.
Projects
None yet
Development

No branches or pull requests

5 participants