-
Notifications
You must be signed in to change notification settings - Fork 47
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
[16.0] Various easy performance boosts #2340
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice imp!
Just a note, you don't have to change it right now but for future commits, it would be nice to add the trail Task: {tasknumber}
instead of Odoo task
to help us out when we merge everything in Odoo ;-)
7e4e07b
to
209c13a
Compare
Fixed a bug in TODO for tomorrow: also check if it's worth changing |
341c82f
to
f75aedc
Compare
The way the getter `findVisibleHeader` was implemented as that it received an argument with all the indexes it need to check to find a visible header. This means that if we want to get the first visible col of a sheet, we have to first generate an array with all the indexes of the cols of the sheet, then looping on this array to find a visible col. This was very wasteful as : 1) we created an array that needed to be garbage collected after 2) the array contains all the indexes, but most of the time we only loop on the first few Changed the arguments of `findVisibleHeader` to receive `from` and `to` arguments. Benchmark : on a sheet 26 cols x 10.000 rows filled with numbers, try to delete the last column ----------- Before : ~2050ms. Most time taken by : - Garbage Collection : ~737ms - range() : ~729ms After: ~542ms. Most time taken by : - Garbage Collection : ~124ms - getRowTallestCellSize() : ~105ms Task: 3272878
The methods `moveCellOn*()` in `sheet.ts` did an useless `parseInt()` to loop through the indexes of an array, slightly decreasing the performance. For when we really have to parse a string to an int, Number() is also slightly faster than parseInt(). This saves 20-40ms on a 10.000 rows sheet with 26 columns, when deleting the first column. Task: 3272878
To compute the formatted value of a number, we need to split it into its integer digits and decimal digits. This was done by the function `splitNumber()`, which was using Intl.NumberFormat, which handles everything for us, but is quite slow. Now convert the number to string using Number.toString(), and handle the max number of decimal and the rounding by hand. We will still use Intl.NumberFormat for numbers too big/small, for which Number.toString() returns an exponential notation. Rough benchmark : Sheet 26 cols x 10.000 rows, using a CF on the whole sheet to force the evaluation of the lazy values. ---------------------- w/ sheet filled with integers: old: splitNumber ~299ms new: splitNumber ~9.5ms w/ sheet filled with floats: old: splitNumber ~555ms new: splitNumber ~30ms Task: 3272878
Currently the model create a new array every time `this.handlers` or `this.coreHandlers` are accessed. That means that we create new arrays every time we dispatch a command, leading to quite a bit of garbage collection. When deleting the first column of a 26 x 1000 sheet filled with numbers, initializing the arrays saves ~100ms in garbage collection. Task: 3272878
f75aedc
to
a5169ac
Compare
@@ -46,7 +46,7 @@ export function load(data?: any, verboseImport?: boolean): WorkbookData { | |||
} | |||
} | |||
} | |||
data = JSON.parse(JSON.stringify(data)); | |||
data = deepCopy(data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not imported in the file :o
2990e65
to
b16ef59
Compare
@robodoo r+ |
robodoo rebase-ff 😛 |
Merge method set to rebase and fast-forward. |
The way the getter `findVisibleHeader` was implemented as that it received an argument with all the indexes it need to check to find a visible header. This means that if we want to get the first visible col of a sheet, we have to first generate an array with all the indexes of the cols of the sheet, then looping on this array to find a visible col. This was very wasteful as : 1) we created an array that needed to be garbage collected after 2) the array contains all the indexes, but most of the time we only loop on the first few Changed the arguments of `findVisibleHeader` to receive `from` and `to` arguments. Benchmark : on a sheet 26 cols x 10.000 rows filled with numbers, try to delete the last column ----------- Before : ~2050ms. Most time taken by : - Garbage Collection : ~737ms - range() : ~729ms After: ~542ms. Most time taken by : - Garbage Collection : ~124ms - getRowTallestCellSize() : ~105ms Task: 3272878 Part-of: #2340
The methods `moveCellOn*()` in `sheet.ts` did an useless `parseInt()` to loop through the indexes of an array, slightly decreasing the performance. For when we really have to parse a string to an int, Number() is also slightly faster than parseInt(). This saves 20-40ms on a 10.000 rows sheet with 26 columns, when deleting the first column. Task: 3272878 Part-of: #2340
To compute the formatted value of a number, we need to split it into its integer digits and decimal digits. This was done by the function `splitNumber()`, which was using Intl.NumberFormat, which handles everything for us, but is quite slow. Now convert the number to string using Number.toString(), and handle the max number of decimal and the rounding by hand. We will still use Intl.NumberFormat for numbers too big/small, for which Number.toString() returns an exponential notation. Rough benchmark : Sheet 26 cols x 10.000 rows, using a CF on the whole sheet to force the evaluation of the lazy values. ---------------------- w/ sheet filled with integers: old: splitNumber ~299ms new: splitNumber ~9.5ms w/ sheet filled with floats: Old: splitNumber ~555ms New: splitNumber ~30ms Task: 3272878 Part-of: #2340
Currently the model create a new array every time `this.handlers` or `this.coreHandlers` are accessed. That means that we create new arrays every time we dispatch a command, leading to quite a bit of garbage collection. When deleting the first column of a 26 x 1000 sheet filled with numbers, initializing the arrays saves ~100ms in garbage collection. Task: 3272878 Part-of: #2340
closes #2340 Task: 3272878 Signed-off-by: Rémi Rahir (rar) <[email protected]>
[IMP] header_visibility: improve perfs of
findVisibleHeader
The way the getter
findVisibleHeader
was implemented as that it receivedan argument with all the indexes it need to check to find a visible header.
This means that if we want to get the first visible col of a sheet,
we have to first generate an array with all the indexes of the cols of the
sheet, then looping on this array to find a visible col. This was very
wasteful as :
loop on the first few
Changed the arguments of
findVisibleHeader
to receivefrom
andto
arguments.
Benchmark :
on a sheet 26 cols x 10.000 rows filled with numbers, try to delete the last
column
Before : ~2050ms. Most time taken by :
After: ~542ms. Most time taken by :
[IMP] sheet: move cells methods performance
The methods
moveCellOn*()
insheet.ts
did an uselessparseInt()
toloop through the indexes of an array, slightly decreasing the performance.
For when we really have to parse a string to an int, Number() is also
slightly faster than parseInt().
This saves 20-40ms on a 10.000 rows sheet with 26 columns, when deleting the
first column.
[IMP] formats: performance of
splitNumber()
To compute the formatted value of a number, we need to split it into
its integer digits and decimal digits. This was done by the function
splitNumber()
, which was using Intl.NumberFormat, which handleseverything for us, but is quite slow.
Now convert the number to string using Number.toString(), and handle
the max number of decimal and the rounding by hand. We will still use
Intl.NumberFormat for numbers too big/small, for which Number.toString()
returns an exponential notation.
Rough benchmark :
Sheet 26 cols x 10.000 rows, using a CF on the whole sheet to force the
evaluation of the lazy values.
w/ sheet filled with integers:
old: splitNumber ~299ms
new: splitNumber ~9.5ms
w/ sheet filled with floats:
old: splitNumber ~555ms
new: splitNumber ~30ms
[IMP] model: store handler arrays
Currently the model create a new array every time
this.handlers
orthis.coreHandlers
are accessed. That means thatwe create new arrays every time we dispatch a command, leading to
quite a bit of garbage collection.
When deleting the first column of a 26 x 1000 sheet filled with numbers,
initializing the arrays saves ~100ms in garbage collection.
Odoo task ID : 3272878
review checklist