Changeset 49403 in webkit


Ignore:
Timestamp:
Oct 9, 2009 2:24:28 PM (15 years ago)
Author:
eric@webkit.org
Message:

2009-10-09 Jens Alfke <snej@chromium.org>

Reviewed by Darin Adler.

Optimization: Many StringImpl transformations are no-ops and should just return 'this'
https://bugs.webkit.org/show_bug.cgi?id=30186

Optimized StringImpl methods lower(), stripWhiteSpace() and simplifyWhiteSpace() to
detect no-ops and return this instead of creating a new instance.
Empirical testing shows that the majority of calls to these methods are no-ops, making
this worthwhile even if (in the case of lower()) the non-no-op case is slightly slowed.
Upper() is very rarely a no-op, so it wasn't worthwhile to optimize it.

  • platform/text/StringImpl.cpp: (WebCore::StringImpl::lower): (WebCore::StringImpl::upper): Just add a comment explaining why this wasn't optimized (WebCore::StringImpl::stripWhiteSpace): (WebCore::StringImpl::simplifyWhiteSpace):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r49402 r49403  
     12009-10-09  Jens Alfke  <snej@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4       
     5        Optimization: Many StringImpl transformations are no-ops and should just return 'this'
     6        https://bugs.webkit.org/show_bug.cgi?id=30186
     7
     8        Optimized StringImpl methods lower(), stripWhiteSpace() and simplifyWhiteSpace() to
     9        detect no-ops and return this instead of creating a new instance.
     10        Empirical testing shows that the majority of calls to these methods are no-ops, making
     11        this worthwhile even if (in the case of lower()) the non-no-op case is slightly slowed.
     12        Upper() is very rarely a no-op, so it wasn't worthwhile to optimize it.
     13
     14        * platform/text/StringImpl.cpp:
     15        (WebCore::StringImpl::lower):
     16        (WebCore::StringImpl::upper): Just add a comment explaining why this wasn't optimized
     17        (WebCore::StringImpl::stripWhiteSpace):
     18        (WebCore::StringImpl::simplifyWhiteSpace):
     19
    1202009-10-09  Dirk Schulze  <krit@webkit.org>
    221
  • trunk/WebCore/platform/text/StringImpl.cpp

    r49322 r49403  
    176176PassRefPtr<StringImpl> StringImpl::lower()
    177177{
    178     UChar* data;
    179     PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
     178    // First scan the string for uppercase and non-ASCII characters:
    180179    int32_t length = m_length;
    181 
    182     // Do a faster loop for the case where all the characters are ASCII.
    183180    UChar ored = 0;
     181    bool noUpper = true;
    184182    for (int i = 0; i < length; i++) {
    185183        UChar c = m_data[i];
    186184        ored |= c;
    187         data[i] = toASCIILower(c);
    188     }
    189     if (!(ored & ~0x7F))
     185        noUpper = noUpper && !isASCIIUpper(c);
     186    }
     187   
     188    // Nothing to do if the string is all ASCII with no uppercase.
     189    if (noUpper && !(ored & ~0x7F))
     190        return this;
     191
     192    UChar* data;
     193    RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
     194
     195    if (!(ored & ~0x7F)) {
     196        // Do a faster loop for the case where all the characters are ASCII.
     197        for (int i = 0; i < length; i++) {
     198            UChar c = m_data[i];
     199            data[i] = toASCIILower(c);
     200        }
    190201        return newImpl;
    191 
     202    }
     203   
    192204    // Do a slower implementation for cases that include non-ASCII characters.
    193205    bool error;
     
    204216PassRefPtr<StringImpl> StringImpl::upper()
    205217{
     218    // This function could be optimized for no-op cases the way lower() is,
     219    // but in empirical testing, few actual calls to upper() are no-ops, so
     220    // it wouldn't be worth the extra time for pre-scanning.
    206221    UChar* data;
    207222    PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
     
    288303        end--;
    289304
     305    if (!start && end == m_length - 1)
     306        return this;
    290307    return create(m_data + start, end + 1 - start);
    291308}
     
    330347    const UChar* fromend = from + m_length;
    331348    int outc = 0;
     349    bool changedToSpace = false;
    332350   
    333351    UChar* to = data.characters();
    334352   
    335353    while (true) {
    336         while (from != fromend && isSpaceOrNewline(*from))
     354        while (from != fromend && isSpaceOrNewline(*from)) {
     355            if (*from != ' ')
     356                changedToSpace = true;
    337357            from++;
     358        }
    338359        while (from != fromend && !isSpaceOrNewline(*from))
    339360            to[outc++] = *from++;
     
    346367    if (outc > 0 && to[outc - 1] == ' ')
    347368        outc--;
     369   
     370    if (static_cast<unsigned>(outc) == m_length && !changedToSpace)
     371        return this;
    348372   
    349373    data.shrink(outc);
Note: See TracChangeset for help on using the changeset viewer.