-
-
Notifications
You must be signed in to change notification settings - Fork 861
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
Improve performance of mergeLocaleMessage (#1099) #1101
Conversation
Codecov Report
@@ Coverage Diff @@
## v8.x #1101 +/- ##
=======================================
Coverage 96.49% 96.49%
=======================================
Files 10 10
Lines 913 913
=======================================
Hits 881 881
Misses 32 32
Continue to review full report at Codecov.
|
typeof this._vm.messages[locale] !== 'undefined' && Object.keys(this._vm.messages[locale]).length | ||
? this._vm.messages[locale] | ||
: {}, | ||
message | ||
)) |
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.
Thanks for PR 👍
Could you tell me how this change will improve performance when _vm.messages[locale]
is undefined or empty object ?
This change introduce Object.keys
, which seems to add extra execution time.
I also assume _vm.messages[locale]
is likely to have several messages for many cases, so this change will degrade performance for many cases.
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.
Hi exoego,
Line 769 in 4b34aa9
this._vm.$set(this._vm.messages, locale, merge({}, this._vm.messages[locale] || {}, message)) |
With reference to the current logic, the merge
call becomes either merge({}, this._vm.messages[locale], message)
or merge({}, {}, message)
when _vm.messages[locale]
is defined or undefined respectively. The merge
function loops the messages twice in both cases.
With this change, the messages will only be looped once.
Below simple test gives me the result as follows. The time difference will be greater when there are more messages.
const i18n = new VueI18n({
locale: 'en',
messages: {
ja: { hello: 'world' }
}
})
const start = process.hrtime()
for (let i = 0; i < 1000000; i++) {
i18n.mergeLocaleMessage('en', { foo: 'bar' })
}
const end = process.hrtime(start)
console.log(end)
const start2 = process.hrtime()
for (let i = 0; i < 1000000; i++) {
i18n.mergeLocaleMessage('ja', { foo: 'bar' })
}
const end2 = process.hrtime(start2)
console.log(end2)
// Before the change
// [ 2, 627509043 ]
// [ 3, 271436487 ]
// After the change
// [ 0, 600614057 ]
// [ 0, 417202963 ]
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.
Thanks for explanation and quick benchmark.
The time difference will be greater when there are more messages.
Yes, this is exactly the case I am afraid in the previous comment: _vm.messages[locale]
is likely to have several messages for many cases, so this change will degrade performance for many cases.
Could you tell more detail of your use case #1099, where mergeLocaleMessage
is invoked over undefined or empty message ?
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.
Thanks for your review.
The time difference will be greater when there are more messages.
Sorry for my vague statement, I meant the time difference (before and after the change) will be greater. So the improvement of this pull request will be greater when there are more messages to merge which should be the usual cases.
If I replace { foo: 'bar' }
in above benchmark with an object of 10 keys. The result becomes:
// Before the change
// [ 10, 646949552 ]
// [ 11, 363784417 ]
// After the change
// [ 0, 882620796 ]
// [ 0, 689321051 ]
Could you tell more detail of your use case #1099, where mergeLocaleMessage is invoked over undefined or empty message ?
I just tried to improve the performance without logic change. The use case was introduced in #752 by another person and was released in version 8.15.3.
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.
@cslee
Thank you for your reporting!
I actually tried to check about performance.
The more locale messages, the more noticeable the performance degradation becomes.
This is a problem.
You can solve the performance degradation with PR.
Thanks! :)
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.
This change can let watch failed with Vue2.
typeof this._vm.messages[locale] !== 'undefined' && Object.keys(this._vm.messages[locale]).length | ||
? this._vm.messages[locale] | ||
: {}, | ||
message | ||
)) |
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.
@cslee
Thank you for your reporting!
I actually tried to check about performance.
The more locale messages, the more noticeable the performance degradation becomes.
This is a problem.
You can solve the performance degradation with PR.
Thanks! :)
No description provided.