Skip to content
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

Lift literal expressions to top-level constants in JavaScript code generation #4090

Open
kemo-1 opened this issue Dec 17, 2024 · 7 comments
Open
Labels
help wanted Contributions encouraged priority:medium

Comments

@kemo-1
Copy link

kemo-1 commented Dec 17, 2024

  1. make a massive list in gleam

you can use gleam csv package to turn a csv file to gleam list then do io.debug(parssed_csv)

  1. make the list be let list = [ // here will be the long list ]

  2. do some computation to the data for me it was getting a specific element from the list

  3. change the list from let list = to const list

(make sure its a process that would take 1 or more seconds so you can notice the difference visually)

i noticed this in a lustre application i needed to get the element number 34 from list number 77 this took 4 seconds just by changing the list to const it was instant

( the version this happened on was 1.5 iirc it good to test if it still happens now )

@kemo-1 kemo-1 added the bug Something isn't working label Dec 17, 2024
@joshi-monster
Copy link
Contributor

just for reference, the let version is the one being significantly slower. This only affects the JS target.

It happens because the toList call that the compiler emits for constant lists is too complex for JS engines to figure out that it is a pure function call with constant arguments, and could be hoisted.

@kemo-1
Copy link
Author

kemo-1 commented Dec 17, 2024

glad i wasn't hullcinating thank you

@lpil lpil added help wanted Contributions encouraged priority:medium and removed bug Something isn't working labels Dec 17, 2024
@lpil lpil changed the title Big Performance Difference Bettwen variables and const list Lift literal expressions to top-level constants in JavaScript code generation Dec 17, 2024
@lpil
Copy link
Member

lpil commented Dec 21, 2024

The goal here would be to identify side-effect free expressions that do not depend on any function parameter or other variable data and to lift them to the top level as a JS const. For example:

import { toList } from "./gleam.mjs";
import * as $io from "./gleam/io.mjs";

export function main() {
  let x = toList([1, 2, 3]);
  return $io.debug(x);
}

would become

import { toList } from "./gleam.mjs";
import * as $io from "./gleam/io.mjs";

const x = toList([1, 2, 3]);

export function main() {
  return $io.debug(x);
}

We would also need to decide on some scheme for renaming the variables as they are no longer scoped to just the function, so they could collide if left as-is.

@GearsDatapacks
Copy link
Member

GearsDatapacks commented Dec 22, 2024

How do we decide which expressions to lift? Because something like:

import { toList } from "./gleam.mjs";
import * as $io from "./gleam/io.mjs";

const one = 1;
const two = 2;
const three = 3;
const x = toList([one, two, three]);

export function main() {
  return $io.debug(x);
}

Seems a little over the top.

Also, should we ensure we don't have duplicate constant definitions? So if there were two literal lists,[1, 2, 3] in a single module, we would only generate one constant instead of two.

@lpil
Copy link
Member

lpil commented Dec 22, 2024

Lifting everything seems fine to me. Deduplication could be a nice future addition.

@GearsDatapacks
Copy link
Member

Won't that result in a large increase in generated code size? Is that something we care about at all?

@lpil
Copy link
Member

lpil commented Dec 22, 2024

No because every expression added to the top level will have an identical expression removed from a function. It will be the same amount of code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Contributions encouraged priority:medium
Projects
None yet
Development

No branches or pull requests

4 participants