Bug 97910 - [SVG] Use references are much slower than necessary
Summary: [SVG] Use references are much slower than necessary
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Florin Malita
Depends on:
Reported: 2012-09-28 07:12 PDT by Branimir Lambov
Modified: 2012-10-01 01:12 PDT (History)
4 users (show)

See Also:

Example setting href attribute (3.47 KB, image/svg+xml)
2012-09-28 07:12 PDT, Branimir Lambov
no flags Details
Example creating new 'use' element (3.54 KB, image/svg+xml)
2012-09-28 07:13 PDT, Branimir Lambov
no flags Details
Example without changing reference, demonstrating what the performance should be (3.43 KB, image/svg+xml)
2012-09-28 07:15 PDT, Branimir Lambov
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Branimir Lambov 2012-09-28 07:12:50 PDT
Created attachment 166245 [details]
Example setting href attribute

The attached files contain a hierarchy of 'use' elements to build a graphic containing a few hundred triangles. It is not a problem for Chrome to render the graphic fluidly (use-levels-move), but if a new 'use' element references the graphic (use-levels-new-use), or the element's 'href' is changed (use-levels-set-href), the performance falls dramatically.

WebKit is copying the elements referenced by 'use', which should not be necessary at all. In other tests we have seen that it is actually faster to explicitly recreate referenced nodes with JavaScript than to refer to them with 'use' elements.

Opera does not have this problem, and runs all these examples at ~50 fps.
Comment 1 Branimir Lambov 2012-09-28 07:13:24 PDT
Created attachment 166246 [details]
Example creating new 'use' element
Comment 2 Branimir Lambov 2012-09-28 07:15:50 PDT
Created attachment 166247 [details]
Example without changing reference, demonstrating what the performance should be
Comment 3 Florin Malita 2012-09-28 07:57:34 PDT
(In reply to comment #0)
> WebKit is copying the elements referenced by 'use', which should not be necessary at all.

Deep cloning is likely needed to support full <use> semantics - see http://www.w3.org/TR/SVG/struct.html#UseElement

But the profile for the slow tests does seem odd - most cycles wasted in synchronization and string manipulation code:

  2.77%           chrome  libpthread-2.15.so                  [.] pthread_mutex_unlock
  2.59%           chrome  libpthread-2.15.so                  [.] pthread_mutex_lock
  1.36%          swapper  [kernel.kallsyms]                   [k] mwait_idle_with_hints
  1.35%           chrome  libwebkit.so                        [.] WTF::StringHasher::addCharactersToHash(unsigned short, unsigned short)
  1.25%           chrome  libwebkit.so                        [.] WTF::intHash(unsigned long)
  1.10%           chrome  libwebkit.so                        [.] WTF::OwnPtr<WTF::Mutex>::operator*() const
  1.05%           chrome  libwebkit.so                        [.] WTF::Locker<WTF::Mutex>::Locker(WTF::Mutex&)
  0.96%           chrome  libwebkit.so                        [.] WTF::Mutex::lock()
  0.94%           chrome  libwebkit.so                        [.] WebCore::Node::getFlag(WebCore::Node::NodeFlags) const
  0.79%           chrome  libwebkit.so                        [.] WTF::ThreadRestrictionVerifier::isSafeToUse() const
  0.76%           chrome  libwebkit.so                        [.] WTF::RefPtr<WTF::StringImpl>::get() const
  0.73%           chrome  chrome                              [.] (anonymous namespace)::FL_Previous_No_Check(void*)
  0.71%           chrome  libwebkit.so                        [.] unsigned int WTF::StringHasher::computeHashAndMaskTop8Bits<unsigned short, &(WTF::StringHasher::defaultConverter(unsi
  0.63%           chrome  libpthread-2.15.so                  [.] pthread_getspecific
  0.58%           chrome  chrome                              [.] PackedCache<36, unsigned long>::GetOrDefault(unsigned long, unsigned long) const
  0.57%           chrome  libwebkit.so                        [.] WebCore::Node::document() const
  0.50%           chrome  chrome                              [.] TCMalloc_PageMap3<36>::get(unsigned long) const
  0.50%           chrome  libwebkit.so                        [.] bool WTF::IdentityHashTranslator<WTF::PtrHash<WebCore::SVGElement*> >::equal<WebCore::SVGElement*>(WebCore::SVGElemen
  0.48%           chrome  libwebkit.so                        [.] WTF::Mutex::unlock()
  0.47%         cinnamon  [kernel.kallsyms]                   [k] audit_filter_syscall
  0.46%           chrome  libwebkit.so                        [.] WTF::ThreadIdentifierData::identifier()
  0.44%           chrome  libc-2.15.so                        [.] __memset_sse2
  0.44%           chrome  chrome                              [.] base::subtle::Acquire_Load(long const volatile*)
  0.44%           chrome  chrome (deleted)                    [.] 0x3255b0f
  0.39%           chrome  libwebkit.so                        [.] WTF::String::impl() const
  0.38%           chrome  libwebkit.so                        [.] WTF::Locker<WTF::Mutex>::~Locker()
  0.37%           chrome  libwebkit.so                        [.] void WTF::addIterator<WebCore::SVGElement*, WTF::KeyValuePair<WebCore::SVGElement*, WTF::OwnPtr<WTF::HashSet<WebCore:
  0.37%           chrome  libwebkit.so                        [.] WTF::RefCountedBase::derefBase()
  0.35%           chrome  chrome                              [.] CheckCachedSizeClass(void*)
  0.32%           chrome  libwebkit.so                        [.] WebCore::RenderObject::document() const
  0.32%           chrome  chrome                              [.] (anonymous namespace)::MaskPtr(void*)
  0.32%           chrome  libwebkit.so                        [.] WTF::StringHasher::defaultConverter(unsigned short)
  0.31%           chrome  libwebkit.so                        [.] WTF::doubleHash(unsigned int)
  0.31%           chrome  libwebkit.so                        [.] WTF::RefCountedBase::ref()
  0.28%           chrome  libwebkit.so                        [.] void WTF::removeIterator<WebCore::SVGElement*, WTF::KeyValuePair<WebCore::SVGElement*, WTF::OwnPtr<WTF::HashSet<WebCo
  0.27%           chrome  libwebkit.so                        [.] WTF::currentThread()
  0.27%           chrome  libwebkit.so                        [.] WTF::StringHasher::avalancheBits() const
Comment 4 Nikolas Zimmermann 2012-10-01 01:12:23 PDT
See 97905 comment #4 for a way out of this mess.