Boost logo

Boost :

Subject: Re: [boost] [uuids] On boost::uuids::uuid operator == performance.
From: Michael Kochetkov (michael.kv_at_[hidden])
Date: 2012-04-16 14:31:00


> Interestingly, if I try the following program, the "stupid" my_memcmp
> produces the fastest result.
My results for your code are:
Eq16 -- 100%
my_memcmp -- 119,46 %
memcmp -- 153.94 %
operator == -- 181.03 %

I cannot see how it may be in your case other then:
1. You are wrong about your results.
2. VS2005 has very small default alignment.

For the second case you may add
#pragma pack(push,16)
#pragma pack(pop)

in the proper
#if defined(_MSC_VER)
sections in uuid.hpp.

BTW if you are interested in the final result you do need to initialize your
uuids with some random values. VC initializes all bytes with zeros and is
smart enough to remember that id1 does not change:
        xor edi, edi
        mov DWORD PTR _id2$[esp+40], eax
        mov DWORD PTR _id2$[esp+44], eax
        mov DWORD PTR _id2$[esp+48], eax
        mov DWORD PTR _id2$[esp+52], eax
....

$LN3_at_main:
; Line 39
        cmp edi, DWORD PTR _id2$[esp+40]
        jne SHORT $LN8_at_main
        cmp edi, DWORD PTR _id2$[esp+44]
        jne SHORT $LN8_at_main
        cmp edi, DWORD PTR _id2$[esp+48]
        jne SHORT $LN8_at_main
        cmp edi, DWORD PTR _id2$[esp+52]
        jne SHORT $LN8_at_main
        mov ecx, 1
        jmp SHORT $LN9_at_main
$LN8_at_main:
        xor ecx, ecx
$LN9_at_main:
        movzx ecx, cl
; Line 42
        mov edx, eax
        add esi, ecx
        and edx, -2147483633 ; 8000000fH
        jns SHORT $LN38_at_main
        dec edx
        or edx, -16 ; fffffff0H
        inc edx
$LN38_at_main:
        add BYTE PTR _id2$[esp+edx+40], al
        lea ecx, DWORD PTR _id2$[esp+edx+40]
        inc eax
        cmp eax, 100000000 ; 05f5e100H
        jl SHORT $LN3_at_main

as you may see edi never changes and VC event do not bother itself to
allocate memory for id1. All id1 bytes are represented with edi.

--
Michael Kochetkov
> 
> #include <boost/uuid/uuid.hpp>
> 
> #include <iostream>
> 
> #include <windows.h>
> #include <mmsystem.h>
> 
> typedef unsigned uint32_t;
> 
> inline bool Eq16( unsigned char const * p, unsigned char const * q ) {
>     return *reinterpret_cast<const uint32_t*>( p   ) ==
> *reinterpret_cast<const uint32_t*>( q   )
>         && *reinterpret_cast<const uint32_t*>( p+4 ) ==
> *reinterpret_cast<const uint32_t*>( q+4 )
>         && *reinterpret_cast<const uint32_t*>( p+8 ) ==
> *reinterpret_cast<const uint32_t*>( q+8 )
>         && *reinterpret_cast<const uint32_t*>( p+12) ==
> *reinterpret_cast<const uint32_t*>( q+12); }
> 
> inline bool my_memcmp( unsigned char const * p, unsigned char const * q,
> size_t n ) {
>     for( size_t i = 0; i < n; ++i )
>     {
>         if( p[i] != q[i] ) return false;
>     }
> 
>     return true;
> }
> 
> int main()
> {
>     boost::uuids::uuid id1 = {}, id2 = {};
> 
>     int const N = 100000000;
> 
>     DWORD t1 = timeGetTime();
> 
>     int s = 0;
> 
>     for( int i = 0; i < N; ++i )
>     {
>         //s += ( id1 == id2 );
>         //s += Eq16( id1.data, id2.data );
>         //s += memcmp( id1.data, id2.data, 16 );
>         s += my_memcmp( id1.data, id2.data, 16 );
>         id2.data[ i % 16 ] += i & 0xFF;
>     }
> 
>     DWORD t2 = timeGetTime();
> 
>     std::cout << s << ": " << t2 - t1 << std::endl; }
> 
> 
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk