Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: Source/core/dom/ElementData.h

Issue 177613003: Consistently cache ElementData::length() before loops (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix test failure Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/dom/ElementData.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); } 55 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); }
56 const SpaceSplitString& classNames() const { return m_classNames; } 56 const SpaceSplitString& classNames() const { return m_classNames; }
57 57
58 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; } 58 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; }
59 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; } 59 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; }
60 60
61 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } 61 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
62 62
63 const StylePropertySet* presentationAttributeStyle() const; 63 const StylePropertySet* presentationAttributeStyle() const;
64 64
65 // This is not a trivial getter and its return value should be cached for pe rformance.
65 size_t length() const; 66 size_t length() const;
66 bool isEmpty() const { return !length(); } 67 bool isEmpty() const { return !length(); }
67 68
68 const Attribute* attributeItem(unsigned index) const; 69 const Attribute* attributeItem(unsigned index) const;
69 const Attribute* getAttributeItem(const QualifiedName&) const; 70 const Attribute* getAttributeItem(const QualifiedName&) const;
70 size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = f alse) const; 71 size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = f alse) const;
71 size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttr ibuteCase) const; 72 size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttr ibuteCase) const;
72 size_t getAttrIndex(Attr*) const; 73 size_t getAttrIndex(Attr*) const;
73 74
74 bool hasID() const { return !m_idForStyleResolution.isNull(); } 75 bool hasID() const { return !m_idForStyleResolution.isNull(); }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 { 197 {
197 if (m_isUnique) 198 if (m_isUnique)
198 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be gin(); 199 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be gin();
199 return static_cast<const ShareableElementData*>(this)->m_attributeArray; 200 return static_cast<const ShareableElementData*>(this)->m_attributeArray;
200 } 201 }
201 202
202 inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const 203 inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const
203 { 204 {
204 const Attribute* begin = attributeBase(); 205 const Attribute* begin = attributeBase();
205 // Cache length for performance as ElementData::length() contains a conditio nal branch. 206 // Cache length for performance as ElementData::length() contains a conditio nal branch.
206 unsigned len = length(); 207 unsigned length = this->length();
207 for (unsigned i = 0; i < len; ++i) { 208 for (unsigned i = 0; i < length; ++i) {
208 const Attribute& attribute = begin[i]; 209 const Attribute& attribute = begin[i];
209 if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase) ) 210 if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase) )
210 return i; 211 return i;
211 } 212 }
212 return kNotFound; 213 return kNotFound;
213 } 214 }
214 215
215 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller 216 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller
216 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). 217 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
217 inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const 218 inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
218 { 219 {
219 // Cache length for performance as ElementData::length() contains a conditio nal branch. 220 // Cache length for performance as ElementData::length() contains a conditio nal branch.
220 unsigned len = length(); 221 unsigned length = this->length();
221 bool doSlowCheck = shouldIgnoreAttributeCase; 222 bool doSlowCheck = shouldIgnoreAttributeCase;
222 223
223 // Optimize for the case where the attribute exists and its name exactly mat ches. 224 // Optimize for the case where the attribute exists and its name exactly mat ches.
224 const Attribute* begin = attributeBase(); 225 const Attribute* begin = attributeBase();
225 for (unsigned i = 0; i < len; ++i) { 226 for (unsigned i = 0; i < length; ++i) {
226 const Attribute& attribute = begin[i]; 227 const Attribute& attribute = begin[i];
227 // FIXME: Why check the prefix? Namespaces should be all that matter. 228 // FIXME: Why check the prefix? Namespaces should be all that matter.
228 // Most attributes (all of HTML and CSS) have no namespace. 229 // Most attributes (all of HTML and CSS) have no namespace.
229 if (!attribute.name().hasPrefix()) { 230 if (!attribute.name().hasPrefix()) {
230 if (name == attribute.localName()) 231 if (name == attribute.localName())
231 return i; 232 return i;
232 } else { 233 } else {
233 doSlowCheck = true; 234 doSlowCheck = true;
234 } 235 }
235 } 236 }
236 237
237 if (doSlowCheck) 238 if (doSlowCheck)
238 return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase); 239 return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
239 return kNotFound; 240 return kNotFound;
240 } 241 }
241 242
242 inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const 243 inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
243 { 244 {
244 const Attribute* begin = attributeBase(); 245 const Attribute* begin = attributeBase();
245 for (unsigned i = 0; i < length(); ++i) { 246 unsigned length = this->length();
247 for (unsigned i = 0; i < length; ++i) {
246 const Attribute& attribute = begin[i]; 248 const Attribute& attribute = begin[i];
247 if (attribute.name().matches(name)) 249 if (attribute.name().matches(name))
248 return &attribute; 250 return &attribute;
249 } 251 }
250 return 0; 252 return 0;
251 } 253 }
252 254
253 inline const Attribute* ElementData::attributeItem(unsigned index) const 255 inline const Attribute* ElementData::attributeItem(unsigned index) const
254 { 256 {
255 RELEASE_ASSERT(index < length()); 257 RELEASE_ASSERT(index < length());
(...skipping 11 matching lines...) Expand all
267 } 269 }
268 270
269 inline Attribute* UniqueElementData::attributeItem(unsigned index) 271 inline Attribute* UniqueElementData::attributeItem(unsigned index)
270 { 272 {
271 return &m_attributeVector.at(index); 273 return &m_attributeVector.at(index);
272 } 274 }
273 275
274 } // namespace WebCore 276 } // namespace WebCore
275 277
276 #endif // ElementData_h 278 #endif // ElementData_h
OLDNEW
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/dom/ElementData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698