Skip to content

Optimize kebabify#207

Merged
xymostech merged 4 commits into
Khan:masterfrom
lencioni:kebabify
Mar 6, 2017
Merged

Optimize kebabify#207
xymostech merged 4 commits into
Khan:masterfrom
lencioni:kebabify

Conversation

@lencioni
Copy link
Copy Markdown
Collaborator

@lencioni lencioni commented Mar 5, 2017

By passing a function to replace, we can do the uppercase to lowercase
conversion at the same time. This is pretty much the exact example that
MDN gives, with the only difference being that we aren't checking
against the offset here to avoid adding "-" at the beginning of the
string:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Using_an_inline_function_that_modifies_the_matched_characters

In my profiling, this seems to make kebabify 50% faster (50ms -> 25ms).

Copy link
Copy Markdown
Contributor

@xymostech xymostech left a comment

Choose a reason for hiding this comment

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

LGTM! just a small style nit to fix up :)

Comment thread tests/util_test.js
it('forces -ms-', () => {
assert.equal(kebabifyStyleName('msFooBarBaz'), '-ms-foo-bar-baz');
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

<3 <3

Comment thread src/util.js Outdated
if (result.slice(0, 3) === 'ms-') {
return `-${result}`;
}
return result;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: we use 4-space indents

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done!

Comment thread src/util.js Outdated

export const kebabifyStyleName = (string /* : string */) /* : string */ => {
const result = string.replace(UPPERCASE_RE, UPPERCASE_RE_TO_KEBAB);
if (result.slice(0, 3) === 'ms-') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this the fastest way to check this? It seems like checking result[0] === "ms" && result[1] === "s" && result[2] === "-" might be faster than slicing the string, but is also really ugly. Maybe that's what .startsWith() does, but not everything supports it yet...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This microbenchmark shows bracket is probably the way to go. Not sure if it will really matter much in practice, but it is simple enough so I'll make the change.
https://jsperf.com/slice-vs-bracket-string-check/1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I made a maybe-more-useful microbenchmark that actually tests strings that start with ms- and it also agrees (much more strongly actually) so this looks great! :) https://jsperf.com/slice-vs-bracket-string-check-ms

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ah, in that case, maybe we should use a similar approach in importantify?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added a similar optimization to my importantify PR: bd0a575

lencioni and others added 4 commits March 6, 2017 13:51
My refactoring caused test coverage to drop, so I decided to add some
unit tests here. They pass before and after my refactoring.
By passing a function to replace, we can do the uppercase to lowercase
conversion at the same time. This is pretty much the exact example that
MDN gives, with the only difference being that we aren't checking
against the offset here to avoid adding "-" at the beginning of the
string:

  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Using_an_inline_function_that_modifies_the_matched_characters

In my profiling, this seems to make kebabify 50% faster (50ms -> 25ms).
Now that we've simplified kebabify, there really isn't much value in
having it be in its own function like this. Moving it into
kebabifyStyleName to simplify and optimize.
This avoids an often-unnecessary regex run, which makes this function
run a little faster. I first went with str.slice, but benchmarking
showed that to be 18% slower than bracket access.
Copy link
Copy Markdown
Contributor

@xymostech xymostech left a comment

Choose a reason for hiding this comment

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

LGTM now!

@xymostech xymostech merged commit 5d36d56 into Khan:master Mar 6, 2017
@lencioni lencioni deleted the kebabify branch March 6, 2017 23:18
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.

2 participants