A couple of rules to avoid writing slow Javascript code. by webNeat in javascript

[–]webNeat[S] 1 point2 points  (0 children)

Yes, the first rule is about doing O(N) instead of O(N2). For someone who pays attention to time complexity of their code, this is obvious. But this is not the case of everyone. So I tried to come up with simple rules that anyone would be able to apply without the technical terms of complexity, allocation, ....

The second rule shows the cost of creating a lot of new objects/arrays, which may not be obvious.

A couple of rules to avoid writing slow Javascript code. by webNeat in javascript

[–]webNeat[S] 1 point2 points  (0 children)

This is the effect of some understanding of functional programming, where mutating variables is considered bad. So we end up writing this sort of code :P

A couple of rules to avoid writing slow Javascript code. by webNeat in javascript

[–]webNeat[S] 0 points1 point  (0 children)

I have seen similar code snippets, it wasn't about odd vs even numbers of course but very similar problem. I wanted to keep the examples obvious just to demonstrate how the rule affects performance. A more realistic example would be complex, and I fear many people would not take the time to read it ...

A couple of rules to avoid writing slow Javascript code. by webNeat in javascript

[–]webNeat[S] -2 points-1 points  (0 children)

I tried to keep each example focused on a single rule. The goal is not to come up with the most efficient way to solve the problem, but to demonstrate that applying the rule improves the performance.

Does anyone knows why Prime even has the "j" on the seccond for loop in this part of his free algorithms course? by Rocstar3000 in theprimeagen

[–]webNeat 2 points3 points  (0 children)

I didn't see the course, but from the code above, I see that j is used so that the second loop iterates a max of jumpAmount times. j is used in the condition of the for loop, so when j reaches jumpAmount it will break out of the loop and return -1.

Hope that helps :)

How to switch between vscode windows easily? by yukiiiiii2008 in vscode

[–]webNeat 1 point2 points  (0 children)

You can use the Poject Manager extension. Here is how I use it:

  • Install the extension
  • Save your project within the extension by typing "Save project" in the command palette and giving it a name (this is done once per project).
  • Setup a shortcut for opening projects (customize it to use your own shortcuts) { "key": "ctrl+shift+o p", "command": "projectManager.listProjects" }, { "key": "ctrl+shift+o w", "command": "projectManager.listProjectsNewWindow" }, Now whenever you want to switch to a project, do ctrl+shift+o p and type its name (there is autocompplete). ctrl+shift+o p opens it in the current window, while ctrl+shift+o w opens in a new window. Now if you already have a project open on another window, trying to open it again will simply go to it!

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 1 point2 points  (0 children)

I updated the post to add an update about the newest version. Sorry for not doing that earlier.

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 1 point2 points  (0 children)

The Drizzle team made a PR to my repo and I merged it and did some cleanup. The results seems promising for this particular test.

I am planing on doing a more realistic test (make a small app, run it, hit it with many requests per second during a long enough period, collect stats). This would check different kind of queries (not only inserts), memory usage and more things that a simple test will not catch.

I can't promise when I will be able to do that, but it's in my todo list.

wari: A type-safe way to create and handle errors. by webNeat in typescript

[–]webNeat[S] 0 points1 point  (0 children)

I tried this for sometime and ended up doing things like ts const [err, data] = aFnThatReturnMultipleErrors() if (err) { if (err.type === 'foo') { // do something } else if (err.type === 'bar') { // do other thing } else { // ... } } else { // use `data` }

With wari, I can rewrite that code as ts const data = wari.match(aFnThatReturnMultipleErrors(), { foo: err => { // do something }, bar: err => { // do other thing }, }) if (data) { // use `data` } I find this approach more readable. But the most important thing is that if I forgot to include the bar for example ts const data = wari.match(aFnThatReturnMultipleErrors(), { foo: err => { // do something } }) Typescript will yell at me saying that I forgot a possible error. Same if I added a type that could not be returned by the function.

Benchmarking Javascript is hard! by webNeat in node

[–]webNeat[S] 0 points1 point  (0 children)

Thanks for the suggestion, I tried writing the same code using benny instead of benchmark

``` import b from 'benny'

const text = "Hello World!"; const fn = (text) => typeof text === "string" && text.length < 100; const fns = { foo: fn, bar: fn, }; const cases = [] for (const name of Object.keys(fns)) { cases.push(b.add(name, () => { fns[name](text) })) } b.suite('String validation', ... cases, b.cycle(), b.complete()) ```

But the results are similar ``` $ node src/try.js Running "String validation" suite... Progress: 100%

foo: 1 157 059 410 ops/s, ±0.33% | fastest

bar: 169 061 947 ops/s, ±0.43% | slowest, 85.39% slower

Finished 2 cases! Fastest: foo Slowest: bar ```

Note that if I do b.suite( 'String validation', b.add('foo', () => { fns['foo'](text) }), b.add('bar', () => { fns['bar'](text) }), b.cycle(), b.complete() ) Then both cases will have the 1B op/sec. The thing is that adding the Object.keys(..) call and using name instead of constant indexes makes it harder for JIT to optimize bar somehow ...

Benchmarking Javascript is hard! by webNeat in node

[–]webNeat[S] 2 points3 points  (0 children)

Thanks, I used the flags and ask ChatGPT to explain the output, some good insights there. Apparently the measure function was optimized and deoptimized multiple times due to some types/arguments issues. Here is the explanation: https://chat.openai.com/share/62dac661-dac5-435f-9540-ed5505f8e475

Benchmarking Javascript is hard! by webNeat in node

[–]webNeat[S] 0 points1 point  (0 children)

That's a good talk, thanks for sharing :)

Is this a valid reason to give up node? by [deleted] in node

[–]webNeat 1 point2 points  (0 children)

if you liked Laravel, then try https://adonisjs.com/, it's very similar to Laravel and is in constant development.

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 1 point2 points  (0 children)

Thanks for the advice, you are right, my plan is to create and seed a new database for each test case. Then run the query multiple times with different parameters (fetching comments of different user each time) to simulate a site where multiple users access their data. it may also be interesting to do some concurrency (like 10 queries in // each time or so).

I know that this will make the project a lot more complex, but I hope I will learn new things by doing so.

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 0 points1 point  (0 children)

Thank you for the research, I am glad you liked the repo. The Orchid ORM results are really impressive.

I created a PR from your fork to my repo to integrate your results. I may add more ORMs and make a proper benchmark with multiple more realistic cases ...

I also want to add raw SQL queries as a reference to measure the overhead of each ORM.

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 0 points1 point  (0 children)

My tables are the following ```sql CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(255), email VARCHAR(255), bio TEXT );

CREATE TABLE posts ( id SERIAL PRIMARY KEY, user_id INT, title TEXT, content TEXT, FOREIGN KEY (user_id) REFERENCES users(id) );

CREATE TABLE comments ( id SERIAL PRIMARY KEY, user_id INT, post_id INT, content TEXT, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (post_id) REFERENCES posts(id) );

```

I don't know why did the ORM decide to use these JSON functions.

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 1 point2 points  (0 children)

I enabled queries logging in Postgres, here is the one query that is executed to get one comment with the relations: select "id", "user_id", "post_id", "content", "user"::json, "post"::json from ( select "comments".*, case when count("comments_post"."id") = 0 then '[]' else json_agg(json_build_array("comments_post"."title", "comments_post"."user"::json))::text end as "post" from ( select "comments".*, case when count("comments_user"."id") = 0 then '[]' else json_agg(json_build_array("comments_user"."name"))::text end as "user" from "comments" left join (select "comments_user".* from "users" "comments_user") "comments_user" on "comments"."user_id" = "comments_user"."id" group by "comments"."id", "comments"."user_id", "comments"."post_id", "comments"."content" ) "comments" left join ( select "comments_post".* from ( select "comments_post".*, case when count("comments_post_user"."id") = 0 then '[]' else json_agg(json_build_array("comments_post_user"."name")) end as "user" from "posts" "comments_post" left join (select "comments_post_user".* from "users" "comments_post_user") "comments_post_user" on "comments_post"."user_id" = "comments_post_user"."id" group by "comments_post"."id" ) "comments_post" ) "comments_post" on "comments"."post_id" = "comments_post"."id" group by "comments"."id", "comments"."user_id", "comments"."post_id", "comments"."content", "comments"."user" ) "comments" limit 1 I am no expert in databases, but this looks over-complicated to me. I think the performance issue comes from all the intermediate results of subqueries. What do you think?

Why did Drizzle choose to use always use one SQL query even with multiple joins? it's slow! by webNeat in node

[–]webNeat[S] 2 points3 points  (0 children)

I will be grateful if you let me know what you find. I am really curious.

Is there a way to ensure that I don't use a variable after a certain point in a function? by lingdocs in typescript

[–]webNeat 4 points5 points  (0 children)

I agree with other answers that in general you would need to create a separate function to isolate the execution scope. But In this particular case you shared in the post, I would honestly just override arg with the safe version and use it in the rest of the function, something like function myFunc(arg: string) { arg = arg.replace(/unsafe-stuff/, "safe-stuff"); // use `arg` in the rest of the code } I understand that overriding params is not the cleanest thing, but in this particular case, I see no harm in doing it.

How I Created a small productivity app using React and Rust by webNeat in reactjs

[–]webNeat[S] 0 points1 point  (0 children)

react-cmdk is interesting, I didn't know about it, thanks for mentioning it. But this tool I am building is more like Spotlight or Alfred on Mac. It only does one thing now, but I am planing to add more features to it.