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

Fix "return" outside of function issue #5

Closed
wants to merge 2 commits into from
Closed

Fix "return" outside of function issue #5

wants to merge 2 commits into from

Conversation

sahariko
Copy link

@sahariko sahariko commented Dec 17, 2019

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

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

IIFEs are obsolete; that's never an acceptable solution.

I very explicitly chose to export the proper function, which will be much faster, rather than polluting a single function with all the logic of each case.

If I decide to change my perfectly valid node CJS module to avoid top-level return, I'll use another approach.

@sahariko
Copy link
Author

sahariko commented Dec 17, 2019

  1. It's not wrapped with an IIFE anymore.
  2. Why would it be faster? The module is cached, so the top-level checks are performed only once, and the if statement is practically the same as the separate if statements that were originally there.

If you don't want to introduce changes due to some philosophical principle that's another thing, but this change is perfectly viable.

@ljharb
Copy link
Member

ljharb commented Dec 17, 2019

There's a cost to all those if statements if isMap is run in a hot path, and in engines where Map doesn't exist, the equivalent of () => false is far faster than doing all the checks each time.

@sahariko
Copy link
Author

Gotcha, I'll try to run some benchmarks later to measure the impact on performance.

@sahariko
Copy link
Author

sahariko commented Dec 17, 2019

Ran some basic benchmark with nanoseconds accuracy with this snippet:

const ITERATIONS = BigInt(100000)
const CASES = ['A', 'B']

const bench = (fn) => {
    let total = BigInt(0)

    for (let i = 0; i < ITERATIONS; i++) {
        const start = process.hrtime.bigint()
        fn()
        const end = process.hrtime.bigint()
        total += (end - start)
    }

    return total / ITERATIONS
}

const testCaseA = () => false
const testCaseB = () => { if (true) return false }

const results = [bench(testCaseA), bench(testCaseB)]

const faster = results[0] < results[1] ? 0 : 1
const slower = 1 - faster

console.log(`Test case A average: ${results[0]}ns`)
console.log(`Test case B average: ${results[1]}ns`)
console.log(`Test case ${CASES[faster]} is faster than test case ${CASES[slower]} by ${results[slower] - results[faster]} nanoseconds on average`)

I ran the above 1000 times, here are the results for the first 10 runs (each run ran 100000 iteration of each test case):

Test case A average: 685ns
Test case B average: 677ns
Test case B is faster than test case A by 8 nanoseconds on average

Test case A average: 737ns
Test case B average: 680ns
Test case B is faster than test case A by 57 nanoseconds on average

Test case A average: 726ns
Test case B average: 681ns
Test case B is faster than test case A by 45 nanoseconds on average

Test case A average: 722ns
Test case B average: 695ns
Test case B is faster than test case A by 27 nanoseconds on average

Test case A average: 707ns
Test case B average: 706ns
Test case B is faster than test case A by 1 nanoseconds on average

Test case A average: 708ns
Test case B average: 701ns
Test case B is faster than test case A by 7 nanoseconds on average

Test case A average: 782ns
Test case B average: 675ns
Test case B is faster than test case A by 107 nanoseconds on average

Test case A average: 756ns
Test case B average: 738ns
Test case B is faster than test case A by 18 nanoseconds on average

Test case A average: 698ns
Test case B average: 700ns
Test case A is faster than test case B by 2 nanoseconds on average

Test case A average: 720ns
Test case B average: 671ns
Test case B is faster than test case A by 49 nanoseconds on average

In conclusion, the difference is negligible at best (no more than 70 nanoseconds in all runs), and if anything marks the if case as faster.

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.

2 participants