remarkjs / remark-gfm

remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists)
https://remark.js.org
MIT License
744 stars 26 forks source link

Performance issue with table #45

Closed yuki-takei closed 1 year ago

yuki-takei commented 1 year ago

Initial checklist

Affected packages and versions

remark-gfm@3.0.1

Link to runnable example

No response

Steps to reproduce

Save the following code as test-remark-gfm.mjs

and run node test-remark-gfm.mjs

import { remark } from 'remark';
import remarkGfm from 'remark-gfm';

const bigTable1 = String.raw`# Big Table 1

| Key  | Value           |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |

`;

const bigTable2 = String.raw`# Big Table 2

| Key  | Value           |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |
| ---- | --------------- |
| k1   | v1              |
| k2   | v2              |
| k3   | v3              |
| k4   | v4              |
| k5   | v5              |
| k6   | v6              |
| k7   | v7              |
| k8   | v8              |
| k9   | v9              |
| k10  | v10             |

`;

main();

async function main() {
  console.time('bigTable1 w/o gfm');
  await remark()
    .process(bigTable1);
  console.timeEnd('bigTable1 w/o gfm');

  console.time('bigTable1 w/  gfm');
  await remark()
    .use(remarkGfm)
    .process(bigTable1);
  console.timeEnd('bigTable1 w/  gfm');

  console.time('bigTable2 w/o gfm');
  await remark()
    .process(bigTable2);
  console.timeEnd('bigTable2 w/o gfm');

  console.time('bigTable2 w/  gfm');
  await remark()
    .use(remarkGfm)
    .process(bigTable2);
  console.timeEnd('bigTable2 w/  gfm');

}

Expected behavior

The "with gfm" situation is fast enough to process against "without gfm".

Actual behavior

Here are the results of the 3 tests.

$ node test-remark-gfm.mjs
bigTable1 w/o gfm: 10.063ms
bigTable1 w/  gfm: 54.546ms
bigTable2 w/o gfm: 2.872ms
bigTable2 w/  gfm: 9.518s

$ node test-remark-gfm.mjs
bigTable1 w/o gfm: 9.001ms
bigTable1 w/  gfm: 48.596ms
bigTable2 w/o gfm: 2.226ms
bigTable2 w/  gfm: 9.196s

$ node test-remark-gfm.mjs
bigTable1 w/o gfm: 8.827ms
bigTable1 w/  gfm: 53.679ms
bigTable2 w/o gfm: 2.773ms
bigTable2 w/  gfm: 10.153s

Runtime

Node v16

Package manager

npm 8, yarn 2

OS

Linux

Build and bundle tools

No response

Note

node: v16.17.1 npm: v8.15.0

With the bigTable2, it takes more time if you add | ---- | --------------- | rows into the table.

Even with the bigTable1, more rows take more time (although not as much as bigTable2).

Murderlon commented 1 year ago

Hi, this has already been reported multiple times in https://github.com/micromark/micromark-extension-gfm-table/issues/6 and https://github.com/micromark/micromark-extension-gfm-table/issues/9

Here is my answer from one of them: https://github.com/micromark/micromark-extension-gfm-table/issues/6#issuecomment-1328063582

github-actions[bot] commented 1 year ago

Hi! This was closed. Team: If this was fixed, please add phase/solved. Otherwise, please add one of the no/* labels.

github-actions[bot] commented 1 year ago

Hi! Thanks for taking the time to contribute!

Because we treat issues as our backlog, we close duplicates to focus our work and not have to touch the same chunk of code for the same reason multiple times. This is also why we may mark something as duplicate that isn’t an exact duplicate but is closely related.

Thanks, — bb

github-actions[bot] commented 1 year ago

Hi team! It seems this post is a duplicate, but hasn’t been marked as such. Please post a comment w/ Duplicate of #123(no final .) to do so. See GH docs for more info.

Thanks, — bb

Murderlon commented 1 year ago

Duplicate of https://github.com/micromark/micromark-extension-gfm-table/issues/6

yuki-takei commented 1 year ago

@Murderlon Hi. Thank you for your response. I have not been care micromark repositories.

I read https://github.com/micromark/micromark-extension-gfm-table/issues/6 and https://github.com/micromark/micromark-extension-gfm-table/issues/9 now, but there seems to be no real solution at this time.

I think react-markdown is so useful and has awesome interface for React developers. So I look forward to the parser of rust version itegrates with react-markdown. Thanks.

Murderlon commented 1 year ago

Indeed there is no solution yet. Regarding the Rust version, I reckon it's best use case is at build time. Using it in the browser would mean a large WASM binary which may not always be convenient or worth it.