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

node:assert's assert.ok(false) is really slow when using tsx #548

Open
4 of 6 tasks
alcuadrado opened this issue May 7, 2024 · 5 comments
Open
4 of 6 tasks

node:assert's assert.ok(false) is really slow when using tsx #548

alcuadrado opened this issue May 7, 2024 · 5 comments
Labels
bug Something isn't working pending triage

Comments

@alcuadrado
Copy link
Sponsor

alcuadrado commented May 7, 2024

Acknowledgements

  • I read the documentation and searched existing issues to avoid duplicates
  • I understand this is a place to report a confirmed bug (not seek debugging help)
  • I understand this is a collaborative open source project, and relies on community contributions
  • I have read and understood the Contribution guide

Minimal reproduction

(sorry it's inline)

import assert from "node:assert/strict";

// An assert.ok(false) in a nested function with a ton of text (either code or comments) gets really slow.
// The more nested the function is, the slower it is.
// It doesn't happen with assert.equal(true, false), nor assert.ok(false, "message")

function f1() {
  function f2() {
    function f3() {
      function f4() {
        function f5() {
          function f6() {
            function f7() {
              function f8() {
                function f9() {
                  function f10() {
                    function f11() {
                      function f12() {
                        function f13() {
                          function f14() {
                            function f15() {
                              // Tons of commented out lines
                              //
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A
                              // A

                              assert.ok(false);
                            }
                            f15();
                          }
                          f14();
                        }
                        f13();
                      }
                      f12();
                    }
                    f11();
                  }
                  f10();
                }
                f9();
              }
              f8();
            }
            f7();
          }
          f6();
        }
        f5();
      }
      f4();
    }
    f3();
  }
  f2();
}
f1();

Version

4.9.6

Node.js version

22.0.0

Package manager

pnpm

Operating system

Linux

Problem & expected behavior (under 200 words)

  • What happened

When running node:assert's assert.ok(false) with tsx the automatic error message generation becomes notoriously slow.

It seems to get slower the larger the file is, and the deeper the function that call's assert.ok is.

I only tested this with an ESM package, running node --import tsx/esm repro.ts.

It is not slow if I compile the file and run it without tsx.

I have a strong belief that tsx is interfering with this function, making it really slow. As providing an error message to assert.ok works around the performance issue.

  • What I expected

It should be approximately as fast as the compiled version.

  • Error stack trace

No relevant stack traces.

  • Documentation links

No relevant documentation links.

  • Screenshots

No relevant screenshots.

  • Other

Thanks for creating and maintaining this project.

Contributions

  • I'm interested in working on this issue
  • I'm willing to offer financial support
@alcuadrado alcuadrado added bug Something isn't working pending triage labels May 7, 2024
@alcuadrado
Copy link
Sponsor Author

alcuadrado commented May 7, 2024

I may be able to help debug and/or fix this issue, as I'm quite familiar with Node's and v8's stack traces APIs, but I'm not familiar at all with tsx's internals.

@alcuadrado
Copy link
Sponsor Author

I can confirm that the error is also present in v4.0.0 and other versions of node.

@privatenumber
Copy link
Owner

Thanks for the issue!

Would you mind moving the reproduction into a repo that compares the speed between tsx and node using hyperfine or even just time? Curious what you mean by "slow".

@alcuadrado
Copy link
Sponsor Author

Here's the reproduction: https://github.com/alcuadrado/tsx-slow-assert-failure

It runs it on github actions so that you don't need to install it.

In this case, it runs 150 times slower, but we discovered this because of a real-life assert.ok(expression) taking about 30 seconds when the test was originally passing (before expression turned falsy) in ~4ms.

@privatenumber
Copy link
Owner

I boiled down the minimal reproduction further in https://github.com/privatenumber/node-bug-slow and reported it to Node.js:
nodejs/node#52962

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pending triage
Projects
None yet
Development

No branches or pull requests

2 participants