Thanks to visit codestin.com
Credit goes to github.com

Skip to content

remove circular dependencies #2105

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
wants to merge 1 commit into
base: 6.x
Choose a base branch
from

Conversation

iambumblehead
Copy link

@iambumblehead iambumblehead commented May 9, 2025

Removes circular dependencies by lazy-assigning some definitions in module "Universe.js"

Running the below benchmark many times, sometimes the newer version is faster and sometimes the older version is faster and its unclear if there is performance loss or gain...

This benchmark can be used with node's official benchmark.js scripts The last number is the rate of operations measured in ops/sec (higher is better).

bench.immutable.js
import common from '../node-v22.9.0/benchmark/common.js'
import Immutable6X from '../immutable-js6.X/dist/immutable.min.js'
import ImmutableNEW from '../immutable-js/dist/immutable.min.js'

const TYPE6XLISTPUSH = 'type-6.x.listpush'
const TYPE6XMAPBUILD = 'type-6.x.mapbuild'
const TYPENEWLISTPUSH = 'type-new.listpush'
const TYPENEWMAPBUILD = 'type-new.mapbuild'

const bench = common.createBenchmark(main, {
  n: [8000],
  type: [
    TYPE6XLISTPUSH,
    TYPE6XMAPBUILD,
    TYPENEWLISTPUSH,
    TYPENEWMAPBUILD
  ]
})

async function main(conf) {
  // save then return this obj to try bypassing any
  // runtime optimisation identifying this code as unused
  let list = ''

  const type = conf.type
  const n = conf.n

  if (type === TYPE6XLISTPUSH) {
    bench.start()
    list = Immutable6X.List().asMutable()
    for (let ii = 0; ii < n; ii++) {
      list = list.push(ii)
    }
    list = list.asImmutable()
    bench.end(conf.n)
  }

  if (type === TYPENEWLISTPUSH) {
    bench.start()
    list = ImmutableNEW.List().asMutable()
    for (let ii = 0; ii < n; ii++) {
      list = list.push(ii)
    }
    list = list.asImmutable()
    bench.end(conf.n)
  }

  if (type === TYPE6XMAPBUILD) {
    bench.start()
    let obj1024 = {}
    for (let ii = 0; ii < n; ii++) {
      obj1024['x' + ii] = ii
    }
    list = Immutable6X.Map(obj1024)
    bench.end(conf.n)
  }

  if (type === TYPENEWMAPBUILD) {
    bench.start()
    let obj1024 = {}
    for (let ii = 0; ii < n; ii++) {
      obj1024['x' + ii] = ii
    }
    list = Immutable6X.Map(obj1024)
    bench.end(conf.n)
  }

  return list
}
$ node ./bench.immutable.js 
bench.immutable.js type="type-6.x.listpush" n=8000: 710,371.819265781
bench.immutable.js type="type-6.x.mapbuild" n=8000: 356,138.6732766004
bench.immutable.js type="type-new.listpush" n=8000: 799,544.0999542061
bench.immutable.js type="type-new.mapbuild" n=8000: 348,305.6432523858

Copy link
Member

@jdeniau jdeniau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this hard work ! It's really a nice to have to enable tree-shaking ! 🙏

Before reviewing this huge PR, I'd like to understand some things:

You did "move" some functions, like isListprobeIsList. Why did you do that ?
It seems that you did sort imports too. It's a nice to have, but it doesn't seems related to this PR.

Because it make the PR pretty hard to review (+7000 -6000 😨).

Could you undo some of those things to make the PR reviewable, to keep only the minimal changes ? (or for the sorting, open a PR that sort all imports and add an eslint rule that enforce sorted imports).

@jdeniau
Copy link
Member

jdeniau commented May 9, 2025

ping @bdurrer as you did work on that subject too.

@bdurrer
Copy link
Contributor

bdurrer commented May 9, 2025

do we have a test that verifies tree-shaken code still works? I remember that our first (failed) attempt looked good until webpack removed the magic.

@iambumblehead
Copy link
Author

do we have a test that verifies tree-shaken code still works?

the benchmark script imports the rollup-generated dist files. does that count?

import Immutable6X from '../immutable-js6.X/dist/immutable.min.js' // ~59kb
import ImmutableNEW from '../immutable-js/dist/immutable.min.js' // ~56kb

@iambumblehead
Copy link
Author

Could you undo some of those things to make the PR reviewable, to keep only the minimal changes ? (or for the sorting, open a PR that sort all imports and add an eslint rule that enforce sorted imports).

okay

@iambumblehead
Copy link
Author

You did "move" some functions, like isList → probeIsList. Why did you do that ?

Grouping things into a 'probe' module with prefixed 'probe'-naming enables one to intuit where probe-related behaviours are defined and to grep where they are imported. These things helped me to understand and change the sources.

It seems that you did sort imports too. [...] (or for the sorting, open a PR that sort all imports and add an eslint rule that enforce sorted imports).

Okay. Things were moved around without any awareness of order of imports. A separate PR could be made for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants