2

If I need to see if a certain value is in a string, is it better for performance to use the .test() method or the .search() method?

Example with .search():

var myRegExp = '/Orange/',
    myString = 'This is a string with the word "Orange."';

if(myString.search(myRegExp) != -1) {
    // Do code here
}

Example with .test():

var myRegExp = '/Orange/',
    myString = 'This is a string with the world "Orange."';

if(myRegExp.test(myString)) {
    // Do code here
}

Ultimately, what I'm doing is searching for a specific class name in string. The element would contain multiple classes, so I'd need to find if one of the classes is in it.

Example Markup:

<ul>
    <li class="expandable expanded">
        <ul>
            <li>Text</li>
        </ul>
    <li>
    <li class="expandable collapsed">
        <ul>
            <li>Text</li>
        </ul>
    </li>
</ul>

So, I'm adding a click event to the list items, if they have the class name "expanded" they need to behave one way, if they have the class name "collapsed" they need to behave another.

So, essentially, something like this.

element.addEventListener('click',function(e) {
    if( /* e.target has class name of expanded */ ) {
        // Do certain code
    } else {
        // Do other code
    }
}

I am using jQuery, and I am open to suggestions, but I feel this situation would be better served with native javascript. So, which method would give the best performance? Or is there another method that would be even better?

RussellUresti
  • 6,211
  • 4
  • 28
  • 26

3 Answers3

5

Well, if you are using jQuery, you can do this simply with

element.addEventListener('click',function(e) {
    if( $(e.target).hasClass('expanded' ) {
        // Do certain code
    } else {
        // Do other code
    }
}

If you don't want to create a jQuery object for whatever reason (e.g. performance) you could use this function, adapted from the source of $().hasClass():

function hasClass ( el, selector ) {
    var className = " " + selector + " ";

    if ( (" " + el.className + " ").replace(/[\n\t]/g, " ").indexOf( className ) > -1 ) {
        return true;
    }

    return false;
}

You can then call this like so:

if ( hasClass(e.target, 'expanded') ) {

Personally, I would go for the jQuery approach if you already have it loaded.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Well, I have the library loaded, but the page is pretty script intensive, so I'd like to optimize every last bit of performance I can. What this does tell me, though, is that instead of .test() or .search(), the jQuery team decided to use .indexOf() to see if the value is in the string or not, which I hadn't thought of, and may be the best performance route. – RussellUresti Oct 12 '10 at 19:20
  • @RusselUrest What this answer should be telling you is: don't worry about doing this yourself, just use the `hasClass()` function – Josh Stodola Oct 12 '10 at 19:21
  • 2
    A comparison between jQuery and pure JS solutions: http://jsperf.com/pure-js-hasclass-vs-jquery-hasclass @Josh This function is not the same as the jQuery hasClass function -- it doesn't require a jQuery selector object. – lonesomeday Oct 12 '10 at 19:37
  • @lonesomday Regardless, it is redundant. He has the jQuery library loaded, there is no reason to roll your own function that performs an identical task. – Josh Stodola Oct 12 '10 at 19:51
  • @Josh Well, performance -- not requiring a jQuery selection should be faster (slightly). (I wrote the test wrong originally, hence the odd performance stats in Chrome.) – lonesomeday Oct 12 '10 at 19:56
  • @Josh Having the library available doesn't mean you have to use everything it offers. Native JS is sometimes faster than using jQuery wrappers because, often, jQuery will call a function that calls a function that calls a function that finally performs some code and returns a value -- this can add unnecessary execution time. When you have a library, you shouldn't use it as a crutch; if there is a more efficient way to do something, use that. – RussellUresti Oct 12 '10 at 21:00
  • @RusselUresti @lonesome I find it funny that we are discussing Javascript performance, all the while you are ignoring the fact that including the library adds significant weight to your pages. Re-writing existing functions adds *even more* weight. That weight is far more detrimental than any execution speeds. Where do you think performance matters most, with the client CPU or with their Internet connection? The answer is *obvious*. – Josh Stodola Oct 12 '10 at 21:32
  • @Josh As I said in my original answer, "Personally, I would go for the jQuery approach" I agree that in this case, the performance benefit is not worth the additional code & effort, but it's still an interesting exercise in terms of optimisation -- particularly for complex web apps. – lonesomeday Oct 12 '10 at 21:37
  • @Josh I'm not sure we have the same definition of "performance". Adding the library would only cause an additional file to be loaded on page load, and if you load that through a CDN the browser will use an extra thread, so page load time wouldn't increase that much at all. Or you could lazy load the script after the page is finished loading, so the library wouldn't affect initial page load at all. Meanwhile, if you have a script intensive site, every interaction the user has will cause additional performance delays if you write your code poorly. I'm talking execution time, not page load time. – RussellUresti Oct 12 '10 at 21:42
3

test() returns true or false. search() returns the position of the match, or -1 if no match is found.

So, i think test() would be faster.

mac
  • 108
  • 5
  • 1
    Yep, through testing, it turns out test() is faster than search(). test() against indexOf() though is a bit more unclear. indexOf() is faster for most browsers by about 10%, but in Chrome, test() is faster by over 50%, so I guess it depends on who uses your site. – RussellUresti Oct 13 '10 at 15:47
0

I had same question, after doing some readings I have identified that using native string method indexOf is the best method on performance perspective. This test proofs that also. So apporpriate way would be

var searchStr = 'Orange',
    myString = 'This is a string with the world "Orange."';

if(myString.indexOf(searchStr) != -1) {
    // Do code here
}

Although this question is somewhat old it is still useful. I have found that this question is also has good explanations.

Community
  • 1
  • 1
Ruwanka De Silva
  • 3,555
  • 6
  • 35
  • 51