Changeset 106154 in webkit


Ignore:
Timestamp:
Jan 27, 2012, 2:47:39 PM (14 years ago)
Author:
benjamin@webkit.org
Message:

Speed up the prefix matching of cssPropertyName()
https://bugs.webkit.org/show_bug.cgi?id=77158

Patch by Benjamin Poulain <bpoulain@apple.com> on 2012-01-27
Reviewed by Geoffrey Garen.

This patch improves the performance by:
-not checking the PropertyName with all 7 prefix

(now, in the worse case, 2 prefixes are checked)

-avoiding the conversion 8bits->16bits by using String::operator[]

instead of ::characters()

To avoid checking every prefix, the code branch based on the first
characters of the propertyName.
The remaining of the prefix is checked character by characters like before.

When accessing CSS property, this gives a 13% improvement when there is no prefix.
There is no performance regression for the matching of prefix, including for the first one
of the previous matching code ("css").

  • bindings/js/JSCSSStyleDeclarationCustom.cpp:

():
(WebCore::matchesCSSPropertyNamePrefix):
(WebCore):
(WebCore::getCSSPropertyNamePrefix):
(WebCore::cssPropertyName):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r106150 r106154  
     12012-01-27  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        Speed up the prefix matching of cssPropertyName()
     4        https://bugs.webkit.org/show_bug.cgi?id=77158
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch improves the performance by:
     9        -not checking the PropertyName with all 7 prefix
     10         (now, in the worse case, 2 prefixes are checked)
     11        -avoiding the conversion 8bits->16bits by using String::operator[]
     12         instead of ::characters()
     13
     14        To avoid checking every prefix, the code branch based on the first
     15        characters of the propertyName.
     16        The remaining of the prefix is checked character by characters like before.
     17
     18        When accessing CSS property, this gives a 13% improvement when there is no prefix.
     19        There is no performance regression for the matching of prefix, including for the first one
     20        of the previous matching code ("css").
     21
     22        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
     23        ():
     24        (WebCore::matchesCSSPropertyNamePrefix):
     25        (WebCore):
     26        (WebCore::getCSSPropertyNamePrefix):
     27        (WebCore::cssPropertyName):
     28
    1292012-01-27  Ken Buchanan  <kenrb@chromium.org>
    230
  • trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp

    r105698 r106154  
    5757}
    5858
    59 // Check for a CSS prefix.
    60 // Passed prefix is all lowercase.
    61 // First character of the prefix within the property name may be upper or lowercase.
    62 // Other characters in the prefix within the property name must be lowercase.
    63 // The prefix within the property name must be followed by a capital letter.
    64 static bool hasCSSPropertyNamePrefix(const Identifier& propertyName, const char* prefix)
    65 {
     59enum PropertyNamePrefix
     60{
     61    PropertyNamePrefixNone,
     62    PropertyNamePrefixCSS,
     63    PropertyNamePrefixPixel,
     64    PropertyNamePrefixPos,
     65    PropertyNamePrefixApple,
     66    PropertyNamePrefixEpub,
     67    PropertyNamePrefixKHTML,
     68    PropertyNamePrefixWebKit
     69};
     70
     71template<size_t prefixCStringLength>
     72static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
     73{
     74    size_t prefixLength = prefixCStringLength - 1;
     75
     76    ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
     77    const size_t offset = 1;
     78
    6679#ifndef NDEBUG
    67     ASSERT(*prefix);
    68     for (const char* p = prefix; *p; ++p)
    69         ASSERT(isASCIILower(*p));
     80    for (size_t i = 0; i < prefixLength; ++i)
     81        ASSERT(isASCIILower(prefix[i]));
     82    ASSERT(!prefix[prefixLength]);
    7083    ASSERT(propertyName.length());
    7184#endif
    7285
    73     if (toASCIILower(propertyName.characters()[0]) != prefix[0])
     86    // The prefix within the property name must be followed by a capital letter.
     87    // Other characters in the prefix within the property name must be lowercase.
     88    if (propertyName.length() < (prefixLength + 1))
    7489        return false;
    7590
    76     unsigned length = propertyName.length();
    77     for (unsigned i = 1; i < length; ++i) {
    78         if (!prefix[i])
    79             return isASCIIUpper(propertyName.characters()[i]);
    80         if (propertyName.characters()[i] != prefix[i])
     91    for (size_t i = offset; i < prefixLength; ++i) {
     92        if (propertyName[i] != prefix[i])
    8193            return false;
    8294    }
    83     return false;
     95
     96    if (!isASCIIUpper(propertyName[prefixLength]))
     97        return false;
     98    return true;
     99}
     100
     101static PropertyNamePrefix getCSSPropertyNamePrefix(const StringImpl& propertyName)
     102{
     103    ASSERT(propertyName.length());
     104
     105    // First character of the prefix within the property name may be upper or lowercase.
     106    UChar firstChar = toASCIILower(propertyName[0]);
     107    switch (firstChar) {
     108    case 'a':
     109        if (matchesCSSPropertyNamePrefix(propertyName, "apple"))
     110            return PropertyNamePrefixApple;
     111        break;
     112    case 'c':
     113        if (matchesCSSPropertyNamePrefix(propertyName, "css"))
     114            return PropertyNamePrefixCSS;
     115        break;
     116    case 'k':
     117        if (matchesCSSPropertyNamePrefix(propertyName, "khtml"))
     118            return PropertyNamePrefixKHTML;
     119        break;
     120    case 'e':
     121        if (matchesCSSPropertyNamePrefix(propertyName, "epub"))
     122            return PropertyNamePrefixEpub;
     123        break;
     124    case 'p':
     125        if (matchesCSSPropertyNamePrefix(propertyName, "pos"))
     126            return PropertyNamePrefixPos;
     127        if (matchesCSSPropertyNamePrefix(propertyName, "pixel"))
     128            return PropertyNamePrefixPixel;
     129        break;
     130    case 'w':
     131        if (matchesCSSPropertyNamePrefix(propertyName, "webkit"))
     132            return PropertyNamePrefixWebKit;
     133        break;
     134    default:
     135        break;
     136    }
     137    return PropertyNamePrefixNone;
    84138}
    85139
     
    96150    builder.reserveCapacity(length);
    97151
     152    const StringImpl* propertyNameString = propertyName.impl();
    98153    unsigned i = 0;
    99 
    100     if (hasCSSPropertyNamePrefix(propertyName, "css"))
     154    switch (getCSSPropertyNamePrefix(*propertyNameString)) {
     155    case PropertyNamePrefixNone:
     156        if (isASCIIUpper((*propertyNameString)[0]))
     157            return String();
     158        break;
     159    case PropertyNamePrefixCSS:
    101160        i += 3;
    102     else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
     161        break;
     162    case PropertyNamePrefixPixel:
    103163        i += 5;
    104164        if (hadPixelOrPosPrefix)
    105165            *hadPixelOrPosPrefix = true;
    106     } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
     166        break;
     167    case PropertyNamePrefixPos:
    107168        i += 3;
    108169        if (hadPixelOrPosPrefix)
    109170            *hadPixelOrPosPrefix = true;
    110     } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
    111             || hasCSSPropertyNamePrefix(propertyName, "khtml")
    112             || hasCSSPropertyNamePrefix(propertyName, "apple")
    113             || hasCSSPropertyNamePrefix(propertyName, "epub"))
     171        break;
     172    case PropertyNamePrefixApple:
     173    case PropertyNamePrefixEpub:
     174    case PropertyNamePrefixKHTML:
     175    case PropertyNamePrefixWebKit:
    114176        builder.append('-');
    115     else {
    116         if (isASCIIUpper(propertyName.characters()[0]))
    117             return String();
    118177    }
    119178
Note: See TracChangeset for help on using the changeset viewer.