Bug 115410 - Change HashTraits<RefPtr<P> >::PassOutType to PassRefPtr for better performance
Summary: Change HashTraits<RefPtr<P> >::PassOutType to PassRefPtr for better performance
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mikhail Pozdnyakov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-04-30 04:31 PDT by Mikhail Pozdnyakov
Modified: 2013-05-06 09:41 PDT (History)
6 users (show)

See Also:


Attachments
WIP (1.61 KB, patch)
2013-04-30 04:56 PDT, Mikhail Pozdnyakov
no flags Details | Formatted Diff | Diff
patch (1.86 KB, patch)
2013-05-02 01:53 PDT, Mikhail Pozdnyakov
darin: review-
Details | Formatted Diff | Diff
patch v2 (2.56 KB, patch)
2013-05-03 04:13 PDT, Mikhail Pozdnyakov
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mikhail Pozdnyakov 2013-04-30 04:31:58 PDT
SSIA.
Comment 1 Mikhail Pozdnyakov 2013-04-30 04:56:05 PDT
Created attachment 200099 [details]
WIP

Do we want to take after HashTraits<OwnPtr<P> > and use std::nullptr_t for EmptyValueType?
Comment 2 Mikhail Pozdnyakov 2013-04-30 05:11:52 PDT
Comment on attachment 200099 [details]
WIP

View in context: https://bugs.webkit.org/attachment.cgi?id=200099&action=review

> Source/WTF/wtf/HashTraits.h:145
> +        static PassRefPtr<P> passOut(const RefPtr<P>& value) { return value; }

that would be better to call release here, but that would break constness.
Comment 3 Darin Adler 2013-04-30 08:59:07 PDT
Comment on attachment 200099 [details]
WIP

View in context: https://bugs.webkit.org/attachment.cgi?id=200099&action=review

>> Source/WTF/wtf/HashTraits.h:145
>> +        static PassRefPtr<P> passOut(const RefPtr<P>& value) { return value; }
> 
> that would be better to call release here, but that would break constness.

The release() is where the performance benefit comes from. So this is not useful to do without the release(). This should instead be:

    typedef PassRefPtr<P> PassOutType;
    static PassRefPtr<P> passOut(RefPtr<P>& value) { return value.release(); }

Could you test to see if that compiles on various platforms and what it does?
Comment 4 Darin Adler 2013-04-30 09:00:09 PDT
(In reply to comment #1)
> Do we want to take after HashTraits<OwnPtr<P> > and use std::nullptr_t for EmptyValueType?

Yes, I think we will need to do that so that the take function compiles.
Comment 5 Mikhail Pozdnyakov 2013-04-30 14:21:35 PDT
(In reply to comment #3)
> (From update of attachment 200099 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=200099&action=review
> 
> >> Source/WTF/wtf/HashTraits.h:145
> >> +        static PassRefPtr<P> passOut(const RefPtr<P>& value) { return value; }
> > 
> > that would be better to call release here, but that would break constness.
> 
> The release() is where the performance benefit comes from. So this is not useful to do without the release(). 
This should instead be:
> 
>     typedef PassRefPtr<P> PassOutType;
>     static PassRefPtr<P> passOut(RefPtr<P>& value) { return value.release(); }
> 
> Could you test to see if that compiles on various platforms and what it does?

in order to make it compile-able we will need to use std::nullptr_t as empty type, provide corresponding constructors to RefPtr/PassRefPtr and probably also add one more equal() method to hash translator.. but I can do it :)
Comment 6 Mikhail Pozdnyakov 2013-05-02 01:51:55 PDT
> > The release() is where the performance benefit comes from. So this is not useful to do without the release(). 
> This should instead be:
> > 
> >     typedef PassRefPtr<P> PassOutType;
> >     static PassRefPtr<P> passOut(RefPtr<P>& value) { return value.release(); }
> > 
> > Could you test to see if that compiles on various platforms and what it does?
> 
> in order to make it compile-able we will need to use std::nullptr_t as empty type, provide corresponding constructors to RefPtr/PassRefPtr and probably also add one more equal() method to hash translator.. but I can do it :)

This is actually much more complex to support std::nullptr_t as empty type:
1) there is necessity to add "==" operators accepting nullptr into a lot of places.
2) having both constructors accepting raw pointer to 'T' and std::nullptr_t inside RefPtr/PassRefPtr brings ambiguousness to some calls.

So I would choose another way of solving the initial compiling issue:
having following method inside HashTraits<RefPtr<P> >

       static RefPtr<P>& emptyValue()
        {
            static RefPtr<P>& null = *(new RefPtr<P>);
            return null;
        }
Comment 7 Mikhail Pozdnyakov 2013-05-02 01:53:43 PDT
Created attachment 200304 [details]
patch
Comment 8 Darin Adler 2013-05-02 09:22:55 PDT
(In reply to comment #6)
> So I would choose another way of solving the initial compiling issue:
> having following method inside HashTraits<RefPtr<P> >
> 
>        static RefPtr<P>& emptyValue()
>         {
>             static RefPtr<P>& null = *(new RefPtr<P>);
>             return null;
>         }

This won’t be good for performance. Null needs to be more efficient than this. Please don’t do this.
Comment 9 Darin Adler 2013-05-02 09:25:43 PDT
Comment on attachment 200304 [details]
patch

View in context: https://bugs.webkit.org/attachment.cgi?id=200304&action=review

If we are having trouble making nullptr work, maybe we can make a zero work? I’m sure there is some way to do this. I think you are learning now why I landed this with a FIXME rather than doing this task originally.

> Source/WTF/wtf/HashTraits.h:145
> +        static RefPtr<P>& emptyValue()
> +        {
> +            static RefPtr<P>& null = *(new RefPtr<P>);
> +            return null;
> +        }

I understand this is easier to get right than the alternative, but it’s not going to be efficient to fetch a global variable all the time. Since the whole point of this is to get better performance, we must not make this change!
Comment 10 Mikhail Pozdnyakov 2013-05-03 04:07:53 PDT
(In reply to comment #9)
> (From update of attachment 200304 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=200304&action=review
> 
> If we are having trouble making nullptr work, maybe we can make a zero work? 
think it's gonna work with '0'.

I’m sure there is some way to do this. I think you are learning now why I landed this with a FIXME rather than doing this task originally.
yeah I got it :)
Comment 11 Mikhail Pozdnyakov 2013-05-03 04:13:28 PDT
Created attachment 200406 [details]
patch v2

Use '0' as empty value.
Comment 12 Mikhail Pozdnyakov 2013-05-03 05:27:08 PDT
Comment on attachment 200406 [details]
patch v2

View in context: https://bugs.webkit.org/attachment.cgi?id=200406&action=review

> Source/WTF/wtf/HashTraits.h:141
> +        static P* emptyValue() { return 0; }

it's probably worth adding "static const bool emptyValueIsZero = true;"
Comment 13 Mikhail Pozdnyakov 2013-05-03 05:33:20 PDT
(In reply to comment #11)
> Created an attachment (id=200406) [details]
> patch v2
> 
> Use '0' as empty value.

An alternate solution could be the following:

template<typename P> struct HashTraits<RefPtr<P> > : SimpleClassHashTraits<RefPtr<P> > {
        ..........
        typedef PassRefPtr<P> PassOutType;
        static PassRefPtr<P> passOut(RefPtr<P>& value) { return value.release(); }
        static PassRefPtr<P> passOut(const RefPtr<P>& value) // Overload for temporary, must be used for empty value only.
        {
            ASSERT(!value);
            return 0;
        }
    };

what do you think?
Comment 14 Darin Adler 2013-05-06 09:07:46 PDT
Comment on attachment 200406 [details]
patch v2

View in context: https://bugs.webkit.org/attachment.cgi?id=200406&action=review

> Source/WTF/wtf/HashTable.h:304
>          template<typename T> static bool equal(const T& a, const T& b) { return HashFunctions::equal(a, b); }
> +        template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }

When we add the two-type equal function template, we should remove the old single-type function template. No need to keep both.

>> Source/WTF/wtf/HashTraits.h:141
>> +        static P* emptyValue() { return 0; }
> 
> it's probably worth adding "static const bool emptyValueIsZero = true;"

Doesn’t need to be added. SimpleClassHashTraits provides that.

> Source/WTF/wtf/HashTraits.h:149
> +        static PassRefPtr<P> passOut(P* value) { return value; }
>          // FIXME: We should consider changing PeekType to a raw pointer for better performance,

I suggest a blank line here so that PassOutType and PeekType are in separate paragraphs.
Comment 15 Mikhail Pozdnyakov 2013-05-06 09:41:13 PDT
Committed r149602: <http://trac.webkit.org/changeset/149602>