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] xlsx: accelerate xlsx export #3949

Closed
wants to merge 5 commits into from
Closed

Conversation

rrahir
Copy link
Collaborator

@rrahir rrahir commented Apr 1, 2024

This Pull request addresses the slowness of the pushElement helper.
The two main improvments concern the iteration over the array elements and the comparison operations.

Benchmark of getXLSX function

On a 30k random string cells (heavy use of pushElement) averaged on 10 runs

Firefox Chrome
Before 153 s 81 s
After 6.2 s 4.8 s

With the same patch applied to the mater branch on RNG's super sheet

Firefox Chrome
Before 351 s 95 s
After 17.4 s 8 s

Description:

description of this task, what is implemented and why it is implemented that way.

Task: : 3733743

review checklist

  • feature is organized in plugin, or UI components
  • support of duplicate sheet (deep copy)
  • in model/core: ranges are Range object, and can be adapted (adaptRanges)
  • in model/UI: ranges are strings (to show the user)
  • undo-able commands (uses this.history.update)
  • multiuser-able commands (has inverse commands and transformations where needed)
  • new/updated/removed commands are documented
  • exportable in excel
  • translations (_t("qmsdf %s", abc))
  • unit tested
  • clean commented code
  • track breaking changes
  • doc is rebuild (npm run doc)
  • status is correct in Odoo

@robodoo
Copy link
Collaborator

robodoo commented Apr 1, 2024

`pushElement` was returning an object but only one of its properties was
used. After this revision, the helper only returns the id inside the
list. It also alleviates the memory print.

Task: 3733743
The borders are already normalized at export time. The code was
denormalizing the renormalizing it without reason.

Task: 3733743
JSON.stringify is way slower than deepEquals to compare objects and
assuming that the keys of the object are not ordered the same way, will
yield false negatives.

e.g.
```javascript
a = {'a':2,'b':4}
b = {'b': 4, 'a':2}
JSON.stringify(a) === JSON.stringify(b) // false
deepEquals(a,b) // true
```

Benchmark of `getXLSX`
======================
(averaged on 10 runs)

- On a 30k random text cells (to force heavy use of pushElement):
  Before: 153 seconds
  After: 10 seconds

- On RNG heavy sheet (patch tested in master):
  Before: 351 seconds
  After : 15 seconds

Task: 3733743
After a first test of strict equalilty, `deepEquals` will make type
comparisons before yielding the strict quality again.
In the context of `pushElement`, we know that we compare same-type
objects, which means we only need to evaluate the strict equality
for primitive types.

Benchmark of `getXLSX`
======================
(averaged on 10 runs)

- On a 30k random text cells (to force heavy use of pushElement):
  Before: 10  seconds
  After:  6.7 seconds

- On RNG heavy sheet (patch tested in master):
  Before: 15  seconds
  After : 9.7 seconds

Task: 3733743
We would evaluate the strict equality of the two arguments twice in case
of primitive (non-null) types but the outcome of that evaluation was
already known.
Comment on lines +150 to +151
propertyList[propertyList.length] = property;
return propertyList.length - 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we re-use len here ?

propertyList[len] = property;
return len;

?

Copy link
Collaborator

@LucasLefevre LucasLefevre left a comment

Choose a reason for hiding this comment

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

Nice ! 👍

Comment on lines +8004 to +8008
<right style=\\"thin\\" color=\\"000000\\"/>
<top/>
<bottom/>
<diagonal/>
</border>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you know what causes theses changes in the snapshot ?

Copy link
Collaborator

@LucasLefevre LucasLefevre left a comment

Choose a reason for hiding this comment

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

robodoo r+ rebase-ff

robodoo pushed a commit that referenced this pull request Apr 8, 2024
`pushElement` was returning an object but only one of its properties was
used. After this revision, the helper only returns the id inside the
list. It also alleviates the memory print.

Task: 3733743
Part-of: #3949
robodoo pushed a commit that referenced this pull request Apr 8, 2024
The borders are already normalized at export time. The code was
denormalizing the renormalizing it without reason.

Task: 3733743
Part-of: #3949
robodoo pushed a commit that referenced this pull request Apr 8, 2024
JSON.stringify is way slower than deepEquals to compare objects and
assuming that the keys of the object are not ordered the same way, will
yield false negatives.

e.g.
```javascript
a = {'a':2,'b':4}
b = {'b': 4, 'a':2}
JSON.stringify(a) === JSON.stringify(b) // false
deepEquals(a,b) // true
```

Benchmark of `getXLSX`
======================
(averaged on 10 runs)

- On a 30k random text cells (to force heavy use of pushElement):
  Before: 153 seconds
  After: 10 seconds

- On RNG heavy sheet (patch tested in master):
  Before: 351 seconds
  After : 15 seconds

Task: 3733743
Part-of: #3949
robodoo pushed a commit that referenced this pull request Apr 8, 2024
After a first test of strict equalilty, `deepEquals` will make type
comparisons before yielding the strict quality again.
In the context of `pushElement`, we know that we compare same-type
objects, which means we only need to evaluate the strict equality
for primitive types.

Benchmark of `getXLSX`
======================
(averaged on 10 runs)

- On a 30k random text cells (to force heavy use of pushElement):
  Before: 10  seconds
  After:  6.7 seconds

- On RNG heavy sheet (patch tested in master):
  Before: 15  seconds
  After : 9.7 seconds

Task: 3733743
Part-of: #3949
robodoo pushed a commit that referenced this pull request Apr 8, 2024
We would evaluate the strict equality of the two arguments twice in case
of primitive (non-null) types but the outcome of that evaluation was
already known.

closes #3949

Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
@robodoo
Copy link
Collaborator

robodoo commented Apr 8, 2024

Merge method set to rebase and fast-forward.

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.

None yet

4 participants