Markus Wanner | 22 Sep 22:24
Gravatar

using empty() instead of size()

Hi,

in rev 805c482bc9bb80cd393be7d3ba01a65377d91d9c I've replaced lots of 
.size() == 0 (and similar) calls with .empty(). For one thing, I 
personally find it clearer and easier to read. And it's considered good 
practice because the implementation for most STL containers is simpler 
and faster.

I didn't notice any improvement with the commit benchmark, but the 
annotate one from nvm.cbench showed speedups between 4% and 15%.

Regards

Markus Wanner (ne Schiltknecht)
Zack Weinberg | 22 Sep 23:14

Re: using empty() instead of size()

On Mon, Sep 22, 2008 at 1:26 PM, Markus Wanner <markus <at> bluegap.ch> wrote:
> in rev 805c482bc9bb80cd393be7d3ba01a65377d91d9c I've replaced lots of
> .size() == 0 (and similar) calls with .empty(). For one thing, I personally
> find it clearer and easier to read. And it's considered good practice
> because the implementation for most STL containers is simpler and faster.
>
> I didn't notice any improvement with the commit benchmark, but the annotate
> one from nvm.cbench showed speedups between 4% and 15%.

I'm honestly surprised .empty() and .size() == 0 don't generate
identical code, but hey.  Thanks!

zw
Markus Wanner | 22 Sep 23:18
Gravatar

Re: using empty() instead of size()

Hi,

Zack Weinberg wrote:
> I'm honestly surprised .empty() and .size() == 0 don't generate
> identical code, but hey.  Thanks!

For example for doubly linked lists, it's pretty simple to tell whether 
they are empty or not, but counting the number of elements in the list 
requires traversing the list.

I'm not sure how other containers are affected. Plus some STL 
implementations might have optimizations for .size() to not require it 
to traverse the elements. However, its an optimization not required by 
the standard, AFAIK.

Regards

Markus
Jens Finkhäuser | 22 Sep 23:23
Favicon
Gravatar

Re: using empty() instead of size()

Spooky.

On Mon, Sep 22, 2008 at 11:18:14PM +0200, Markus Wanner wrote:
> Hi,
>
> Zack Weinberg wrote:
>> I'm honestly surprised .empty() and .size() == 0 don't generate
>> identical code, but hey.  Thanks!
>
> For example for doubly linked lists, it's pretty simple to tell whether  
> they are empty or not, but counting the number of elements in the list  
> requires traversing the list.
>
> I'm not sure how other containers are affected. Plus some STL  
> implementations might have optimizations for .size() to not require it to 
> traverse the elements. However, its an optimization not required by the 
> standard, AFAIK.
>
> Regards
>
> Markus
>
>
>
> _______________________________________________
> Monotone-devel mailing list
> Monotone-devel <at> nongnu.org
> http://lists.nongnu.org/mailman/listinfo/monotone-devel

--

-- 
(Continue reading)

Zack Weinberg | 22 Sep 23:33

Re: using empty() instead of size()

On Mon, Sep 22, 2008 at 2:18 PM, Markus Wanner <markus <at> bluegap.ch> wrote:
>> I'm honestly surprised .empty() and .size() == 0 don't generate
>> identical code, but hey.  Thanks!
>
> For example for doubly linked lists, it's pretty simple to tell whether they
> are empty or not, but counting the number of elements in the list requires
> traversing the list.

Sure, but C++98 requires size() to be O(1) for every container, so
there's really no excuse for a 4-15% performance difference.

zw
Markus Wanner | 22 Sep 23:37
Gravatar

Re: using empty() instead of size()

Hi,

Zack Weinberg wrote:
> Sure, but C++98 requires size() to be O(1) for every container, so
> there's really no excuse for a 4-15% performance difference.

Hm.. I didn't know that, thanks.

Very strange. I'm just re-running the annotate benchmarks...

Regards

Markus
Bruce Stephens | 23 Sep 00:04

Re: using empty() instead of size()

Markus Wanner <markus <at> bluegap.ch> writes:

> Zack Weinberg wrote:
>> Sure, but C++98 requires size() to be O(1) for every container, so
>> there's really no excuse for a 4-15% performance difference.
>
> Hm.. I didn't know that, thanks.

Just because the standard says that doesn't mean that it's so in
implementations, of course.  For example size() in SGI's list may be
linear: <http://www.sgi.com/tech/stl/List.html>.

The standard uses odd terminology (I think, anyway).  There's a table
in 23.1 showing the operations and complexities, and some of the
complexities are "constant", and some are "(Note A)".  This is
explained below the table: "Those entries marked ‘‘(Note A)’’ should
have constant complexity."

I wonder if that's an RFC-style "should"?

I don't have a more recent standard---perhaps this has changed?
Zack Weinberg | 23 Sep 01:23

Re: Re: using empty() instead of size()

On Mon, Sep 22, 2008 at 3:04 PM, Bruce Stephens
<monotone <at> cenderis.demon.co.uk> wrote:
>
> Just because the standard says that doesn't mean that it's so in
> implementations, of course.  For example size() in SGI's list may be
> linear: <http://www.sgi.com/tech/stl/List.html>.

Bleah.

> The standard uses odd terminology (I think, anyway).  There's a table
> in 23.1 showing the operations and complexities, and some of the
> complexities are "constant", and some are "(Note A)".  This is
> explained below the table: "Those entries marked ''(Note A)'' should
> have constant complexity." I wonder if that's an RFC-style "should"?

It might be, yeah.  I saw that myself and wasn't sure what to make of it.

C++98 is all I've got, so I dunno if it's changed either.

zw
Boris | 23 Sep 12:46

Re: Re: using empty() instead of size()

On Tue, 23 Sep 2008 01:23:57 +0200, Zack Weinberg <zackw <at> panix.com> wrote:

> On Mon, Sep 22, 2008 at 3:04 PM, Bruce Stephens
> <monotone <at> cenderis.demon.co.uk> wrote:
>>
>> Just because the standard says that doesn't mean that it's so in
>> implementations, of course.  For example size() in SGI's list may be
>> linear: <http://www.sgi.com/tech/stl/List.html>.
>
> Bleah.
>
>> The standard uses odd terminology (I think, anyway).  There's a table
>> in 23.1 showing the operations and complexities, and some of the
>> complexities are "constant", and some are "(Note A)".  This is
>> explained below the table: "Those entries marked ''(Note A)'' should
>> have constant complexity." I wonder if that's an RFC-style "should"?
>
> It might be, yeah.  I saw that myself and wasn't sure what to make of it.
>
> C++98 is all I've got, so I dunno if it's changed either.

In the latest working draft I find this:

Those entries marked "(Note A)" should have constant complexity. Those  
entries marked "(Note B)" have constant complexity [...]

Compared to the entries marked (Note B) I guess should have means they  
don't need to have constant complexity.

Boris
(Continue reading)

Markus Wanner | 23 Sep 00:09
Gravatar

Re: using empty() instead of size()

Hi,

Zack Weinberg wrote:
> Sure, but C++98 requires size() to be O(1) for every container, so
> there's really no excuse for a 4-15% performance difference.

Here are the results I got from this test run. It's a debian lenny 
machine, comparing these revisions:

  new: 805c482bc9bb80cd393be7d3ba01a65377d91d9c
  ref: d1bd931bd76507267b99e57be07125dbb2335fd5
   (which is from nvm.cvsimport-branch-reconstruction, but
    that does only change rcs_import.cc, so annotate shouldn't
    be affected at all)

>                           annotate-a-ref.csv annotate-a-new.csv     p
> annotate-avg-resident-MiB              30.12              23.72  0.00
>     annotate-avg-size-MiB             125.68             119.28  0.00
> annotate-max-resident-MiB              40.38              34.22  0.00
>     annotate-max-size-MiB             136.90             130.86  0.00
>      annotate-num-samples            2089.20            1982.80  0.16
>      annotate-system-time               0.82               0.85  0.11
>        annotate-user-time               4.35               3.49  0.00
>        annotate-wall-time              10.60              10.06  0.16
>                           annotate-b-ref.csv annotate-b-new.csv     p
> annotate-avg-resident-MiB              17.62              11.75  0.00
>     annotate-avg-size-MiB             110.95             103.95  0.00
> annotate-max-resident-MiB              24.82              18.66  0.00
>     annotate-max-size-MiB             121.46             115.32  0.00
>      annotate-num-samples             702.60             599.80  0.17
(Continue reading)

Zack Weinberg | 23 Sep 01:25

Re: using empty() instead of size()

On Mon, Sep 22, 2008 at 3:09 PM, Markus Wanner <markus <at> bluegap.ch> wrote:
> This leads me to think that the STL implementation doesn't provide an O(1)
> implementation for size()... savings is avg memory consumption seems to
> confirm this, no?

Now that's just bloody weird.  I can't think of any reason size()
would need to *allocate memory*.

Please do carry on with the empty() conversions; I may be doing the
grumpy old man thing about crummy STL implementations, but those are
nonetheless what we have to live with.

zw
Derek Scherger | 23 Sep 04:52

Re: using empty() instead of size()

Even if size does have to traverse a list to count the elements one would expect that traversing an *empty* list should be reasonably quick.
All the same, empty() does seem a bit easier on the eyes and if it wins on performance too then what the heck.

Cheers,
Derek



_______________________________________________
Monotone-devel mailing list
Monotone-devel <at> nongnu.org
http://lists.nongnu.org/mailman/listinfo/monotone-devel
Bruce Stephens | 23 Sep 11:55

Re: using empty() instead of size()

"Derek Scherger" <derek <at> echologic.com> writes:

> Even if size does have to traverse a list to count the elements one would
> expect that traversing an *empty* list should be reasonably quick.

Sure, but presumably the extra cost is traversing a non-empty list to
find that it's not empty.  One would hope that an inlined size()
together with a good optimizing compiler might be able to avoid the
cost, but perhaps that's not feasible.
Ulf Ochsenfahrt | 23 Sep 13:34

Re: Re: using empty() instead of size()

Bruce Stephens wrote:
> "Derek Scherger" <derek <at> echologic.com> writes:
> 
>> Even if size does have to traverse a list to count the elements one would
>> expect that traversing an *empty* list should be reasonably quick.
> 
> Sure, but presumably the extra cost is traversing a non-empty list to
> find that it's not empty.  One would hope that an inlined size()
> together with a good optimizing compiler might be able to avoid the
> cost, but perhaps that's not feasible.

If there is an invalid pointer in the non-empty list, the program can 
crash. If the compiler optimizes (i.e. removes) the list traversal, the 
program doesn't crash. Thus, the optimization would change the runtime 
behavior of the program.

Cheers,

-- Ulf
Bruce Stephens | 23 Sep 14:25

Re: Re: using empty() instead of size()

Ulf Ochsenfahrt <ulf <at> ofahrt.de> writes:

[...]

> If there is an invalid pointer in the non-empty list, the program
> can crash.

It can crash, but this is presumably in the realm of undefined
behaviour, so arbitrary things are permitted to happen.

> If the compiler optimizes (i.e. removes) the list traversal, the
> program doesn't crash. Thus, the optimization would change the
> runtime behavior of the program.

Probably, but I think that's a permitted change.

I'd guess a bug report along those lines ("your optimizer caused my
program not to crash!") would be unlikely to be given a high priority.

An implementation with an O(1) implementation of size() would
presumably also not crash at that point either.
Ulf Ochsenfahrt | 23 Sep 14:56

Re: Re: using empty() instead of size()

Bruce Stephens wrote:
> Ulf Ochsenfahrt <ulf <at> ofahrt.de> writes:
> 
> [...]
> 
>> If there is an invalid pointer in the non-empty list, the program
>> can crash.
> 
> It can crash, but this is presumably in the realm of undefined
> behaviour, so arbitrary things are permitted to happen.
> 
>> If the compiler optimizes (i.e. removes) the list traversal, the
>> program doesn't crash. Thus, the optimization would change the
>> runtime behavior of the program.
> 
> Probably, but I think that's a permitted change.

What about inifinite loops? The linked list could also loop back to itself.

> I'd guess a bug report along those lines ("your optimizer caused my
> program not to crash!") would be unlikely to be given a high priority.

Compiler writers are usually very conservative. I would guess that 'the 
optimizer makes the program behave differently' is a serious enough issue.

> An implementation with an O(1) implementation of size() would
> presumably also not crash at that point either.

True. But the compiler can't know that. The compiler only sees the code, 
it doesn't know what it's supposed to do.

Cheers,

-- Ulf
Bruce Stephens | 23 Sep 15:15

Re: using empty() instead of size()

Ulf Ochsenfahrt <ulf <at> ofahrt.de> writes:

[...]

> What about inifinite loops? The linked list could also loop back to itself.

Is there any guarantee that a std::list is a linked list?  Is it
possible to produce a cycle in a std::list?  Is the behaviour of
size() on such a list defined?

[...]

> Compiler writers are usually very conservative. I would guess that
> the optimizer makes the program behave differently' is a serious
> enough issue.

Even for a program whose behaviour is undefined?  Sometimes it
matters: if there's enough code that's relying on the undefined
behaviour.  In this case I doubt they'd care.

>> An implementation with an O(1) implementation of size() would
>> presumably also not crash at that point either.
>
> True. But the compiler can't know that. The compiler only sees the
> code, it doesn't know what it's supposed to do.

The standard library is part of the language specification, so the
compiler is allowed to know about it.  An implementation might use an
O(n) size() for unoptimized builds and an O(1) implementation when
optimizing.  (I doubt there's any reason to do that, but I don't think
it would be forbidden.)
Ulf Ochsenfahrt | 23 Sep 15:42

Re: Re: using empty() instead of size()

Bruce Stephens wrote:
> Ulf Ochsenfahrt <ulf <at> ofahrt.de> writes:
> 
> [...]
> 
>> What about inifinite loops? The linked list could also loop back to itself.
> 
> Is there any guarantee that a std::list is a linked list?  Is it
> possible to produce a cycle in a std::list?  Is the behaviour of
> size() on such a list defined?

You can access arbitrary memory in C++, so, yes, it is possible. Though 
probably not through the usual std::list api. This ability essentially 
subverts the type system, making otherwise possible optimizations 
potentially dangerous. (Though I hear about differences between O2 and 
O3 compiled code often enough, so the gcc writers apparently sometimes 
make such decisions.)

A friend of mine implemented a gcc extension that checked all memory 
accesses, and tested it on 2 or 3 open source projects, and at least one 
of them used direct memory access as a feature. It specifically edited 
in-memory data structures it knew were there.

> Even for a program whose behaviour is undefined?  Sometimes it
> matters: if there's enough code that's relying on the undefined
> behaviour.  In this case I doubt they'd care.

I believe that there is a significant amount of code that depends on the 
fact that the null pointer is unaccessible and crashes the program.

>>> An implementation with an O(1) implementation of size() would
>>> presumably also not crash at that point either.
>> True. But the compiler can't know that. The compiler only sees the
>> code, it doesn't know what it's supposed to do.
> 
> The standard library is part of the language specification, so the
> compiler is allowed to know about it.  An implementation might use an
> O(n) size() for unoptimized builds and an O(1) implementation when
> optimizing.  (I doubt there's any reason to do that, but I don't think
> it would be forbidden.)

True. I think there is a reasonable case in favor of optimizing size() 
== 0 in this manner. But, given that empty() exists, and given that it 
is potentially behavior-changing, I would probably go for other 
optimizations first.

Cheers,

-- Ulf
Markus Wanner | 23 Sep 18:16
Gravatar

Re: using empty() instead of size()

Hi,

Derek Scherger wrote:
> Even if size does have to traverse a list to count the elements one 
> would expect that traversing an *empty* list should be reasonably quick.

Yeah, but it the list is large, traversing is rather expensive, compared
to aborting and returning false upon seeing the first element, as
empty() can do.

It's the difference between wanting to know the exact size or just being
interested if there are some elements or not.

> All the same, empty() does seem a bit easier on the eyes

Yeah, I also like empty() better.

> and if it wins on performance too then what the heck.

For what it's worth, I suspected the slightly increased binary
size and additional link time required for the nvm.cbr branch's binary
and rerun the benchmark again just exactly the revision before:

  new: 805c482bc9bb80cd393be7d3ba01a65377d91d9c
  ref: 639a3179473e718e8b01b9c99232fa1f81ca7f61

This time I took special care to shut down other services on the machine
so that the benchmark should really be the absolutely only load.

With enough test runs I cannot really confirm the speed gain. See the
three results below. I don't think it's really the nvm.cbr branch, as
the executable didn't grow significantly. It would at least really
surprise me.

I rather think it's not such a good benchmark, because it varies quite a
lot and it seems to measure a lot of disc i/o due to the drop_caches.
I'm not sure we really want to exclude that from our benchmarks, because
normally you run operations such as annotate with quite well populated
caches.

Anyway, sorry for the noise. I've just dropped the comment from NEWS.

Regards

Markus Wanner

>                           annotate-a-ref.csv annotate-a-new.csv     p
> annotate-avg-resident-MiB              23.53              23.49  0.70
>     annotate-avg-size-MiB             118.68             118.62  0.84
> annotate-max-resident-MiB              34.20              34.17  0.00
>     annotate-max-size-MiB             130.86             130.86   nan
>      annotate-num-samples            1753.60            1757.40  0.87
>      annotate-system-time               0.86               0.87  0.67
>        annotate-user-time               3.49               3.50  0.62
>        annotate-wall-time               9.18               9.11  0.27
>                           annotate-b-ref.csv annotate-b-new.csv     p
> annotate-avg-resident-MiB              11.89              11.68  0.44
>     annotate-avg-size-MiB             103.59             103.74  0.75
> annotate-max-resident-MiB              18.63              18.61  0.00
>     annotate-max-size-MiB             115.32             115.32   nan
>      annotate-num-samples             602.20             540.10  0.33
>      annotate-system-time               0.18               0.18  0.70
>        annotate-user-time               0.51               0.52  0.40
>        annotate-wall-time               3.24               2.87  0.26
>                           annotate-c-ref.csv annotate-c-new.csv     p
> annotate-avg-resident-MiB              11.83              11.35  0.31
>     annotate-avg-size-MiB             103.50             102.42  0.41
> annotate-max-resident-MiB              18.28              18.26  0.00
>     annotate-max-size-MiB             114.93             114.93   nan
>      annotate-num-samples             590.60             676.10  0.26
>      annotate-system-time               0.24               0.27  0.12
>        annotate-user-time               0.75               0.75  0.77
>        annotate-wall-time               3.19               3.66  0.21
>                           annotate-d-ref.csv annotate-d-new.csv     p
> annotate-avg-resident-MiB              27.30              26.69  0.18
>     annotate-avg-size-MiB             123.26             122.28  0.18
> annotate-max-resident-MiB              36.11              36.08  0.00
>     annotate-max-size-MiB             132.78             132.78   nan
>      annotate-num-samples            2699.90            2719.70  0.80
>      annotate-system-time               1.07               1.04  0.32
>        annotate-user-time               7.85               7.89  0.33
>        annotate-wall-time              13.87              14.22  0.36
> 
> 
> 
>                           annotate-a-ref.csv annotate-a-new.csv     p
> annotate-avg-resident-MiB              23.42              23.43  0.99
>     annotate-avg-size-MiB             118.53             118.56  0.93
> annotate-max-resident-MiB              34.19              34.17  0.00
>     annotate-max-size-MiB             130.86             130.86   nan
>      annotate-num-samples            1708.50            1741.50  0.37
>      annotate-system-time               0.88               0.85  0.23
>        annotate-user-time               3.48               3.50  0.34
>        annotate-wall-time               9.11               9.16  0.63
>                           annotate-b-ref.csv annotate-b-new.csv     p
> annotate-avg-resident-MiB              11.54              11.67  0.41
>     annotate-avg-size-MiB             101.81             103.59  0.17
> annotate-max-resident-MiB              18.63              18.61  0.00
>     annotate-max-size-MiB             115.32             115.32   nan
>      annotate-num-samples             570.40             566.40  0.83
>      annotate-system-time               0.18               0.19  0.53
>        annotate-user-time               0.52               0.51  0.48
>        annotate-wall-time               3.04               3.02  0.77
>                           annotate-c-ref.csv annotate-c-new.csv     p
> annotate-avg-resident-MiB              12.03              12.20  0.21
>     annotate-avg-size-MiB             104.18             105.06  0.37
> annotate-max-resident-MiB              18.28              18.26  0.00
>     annotate-max-size-MiB             114.93             114.93   nan
>      annotate-num-samples             679.40             602.40  0.28
>      annotate-system-time               0.22               0.26  0.01
>        annotate-user-time               0.76               0.77  0.92
>        annotate-wall-time               3.58               3.22  0.32
>                           annotate-d-ref.csv annotate-d-new.csv     p
> annotate-avg-resident-MiB              27.22              27.25  0.65
>     annotate-avg-size-MiB             122.85             123.24  0.08
> annotate-max-resident-MiB              36.11              36.08  0.00
>     annotate-max-size-MiB             132.78             132.78   nan
>      annotate-num-samples            2674.90            2695.60  0.63
>      annotate-system-time               1.07               1.08  0.79
>        annotate-user-time               7.83               7.85  0.55
>        annotate-wall-time              13.86              13.88  0.86
> 
> 
> 
> 
>                           annotate-a-ref.csv annotate-a-new.csv     p
> annotate-avg-resident-MiB              23.45              22.90  0.31
>     annotate-avg-size-MiB             118.90             117.10  0.31
> annotate-max-resident-MiB              34.19              34.17  0.00
>     annotate-max-size-MiB             130.86             130.86   nan
>      annotate-num-samples            1781.10            1795.00  0.78
>      annotate-system-time               0.86               0.88  0.50
>        annotate-user-time               3.51               3.49  0.49
>        annotate-wall-time               9.17               9.41  0.36
>                           annotate-b-ref.csv annotate-b-new.csv     p
> annotate-avg-resident-MiB              11.28              11.61  0.44
>     annotate-avg-size-MiB             102.36             103.80  0.31
> annotate-max-resident-MiB              18.63              18.60  0.00
>     annotate-max-size-MiB             115.32             115.32   nan
>      annotate-num-samples             588.60             552.80  0.62
>      annotate-system-time               0.18               0.19  0.98
>        annotate-user-time               0.51               0.51  0.88
>        annotate-wall-time               3.17               2.97  0.58
>                           annotate-c-ref.csv annotate-c-new.csv     p
> annotate-avg-resident-MiB              11.74              11.68  0.71
>     annotate-avg-size-MiB             103.83             103.33  0.53
> annotate-max-resident-MiB              18.28              18.26  0.00
>     annotate-max-size-MiB             114.93             114.93   nan
>      annotate-num-samples             608.60             588.40  0.40
>      annotate-system-time               0.28               0.25  0.04
>        annotate-user-time               0.72               0.76  0.05
>        annotate-wall-time               3.28               3.24  0.70
>                           annotate-d-ref.csv annotate-d-new.csv     p
> annotate-avg-resident-MiB              27.23              26.97  0.36
>     annotate-avg-size-MiB             123.17             122.94  0.48
> annotate-max-resident-MiB              36.12              36.09  0.00
>     annotate-max-size-MiB             132.78             132.78   nan
>      annotate-num-samples            2705.70            2786.20  0.53
>      annotate-system-time               1.08               1.07  0.81
>        annotate-user-time               7.82               7.88  0.22
>        annotate-wall-time              13.98              14.52  0.36
Eric Anderson | 24 Sep 01:12
Favicon

Re: using empty() instead of size()

Zack Weinberg writes:
 > On Mon, Sep 22, 2008 at 3:09 PM, Markus Wanner <markus <at> bluegap.ch> wrote:
 > > This leads me to think that the STL implementation doesn't provide an O(1)
 > > implementation for size()... savings is avg memory consumption seems to
 > > confirm this, no?
 > 
 > Now that's just bloody weird.  I can't think of any reason size()
 > would need to *allocate memory*.

Assuming that the code for getting memory usage is derived from the
code I wrote a long time ago (output looks similar, so likely); I
expect that the memory consumption differences are just sampling
effects.  It sampled every 1 second or so, and so changes to runtime
can affect when the memory usage is sampled and hence the estimated
memory usage.  Tools like valgrind in it's massif mode will give you
better memory usage comparisons, but result in big slowdowns.
	-Eric
Markus Wanner | 24 Sep 10:23
Gravatar

Re: using empty() instead of size()

Hi,

Eric Anderson wrote:
> Assuming that the code for getting memory usage is derived from the
> code I wrote a long time ago (output looks similar, so likely); I
> expect that the memory consumption differences are just sampling
> effects.  It sampled every 1 second or so, and so changes to runtime
> can affect when the memory usage is sampled and hence the estimated
> memory usage.

Yeah, I've been questioning the 'avg' value as well. If you now tell me
that sampling is done at 1 second intervals, then I even suspect the max
value to not be very meaningful.

Regards

Markus Wanner
Eric Anderson | 24 Sep 19:39
Favicon

Re: using empty() instead of size()

Markus Wanner writes:
 > Eric Anderson wrote:
 > > Assuming that the code for getting memory usage is derived from the
 > > code I wrote a long time ago (output looks similar, so likely); I
 > > expect that the memory consumption differences are just sampling
 > > effects.  It sampled every 1 second or so, and so changes to runtime
 > > can affect when the memory usage is sampled and hence the estimated
 > > memory usage.
 > 
 > Yeah, I've been questioning the 'avg' value as well. If you now tell me
 > that sampling is done at 1 second intervals, then I even suspect the max
 > value to not be very meaningful.

If a run went on for a while (20-60s), and you ran it multiple times
(I did), it's generally pretty good, but it certainly wasn't something
that should be trusted blindly.  I generally ignored the memory
information unless I was looking at something > 1.5x.
	-Eric
Stephen Leake | 23 Sep 13:07
Favicon

Re: using empty() instead of size()

Markus Wanner <markus <at> bluegap.ch> writes:

>>                           annotate-a-ref.csv annotate-a-new.csv     p
>> annotate-avg-resident-MiB              30.12              23.72  0.00
>>     annotate-avg-size-MiB             125.68             119.28  0.00
>> annotate-max-resident-MiB              40.38              34.22  0.00
>>     annotate-max-size-MiB             136.90             130.86  0.00
>>      annotate-num-samples            2089.20            1982.80  0.16
>>      annotate-system-time               0.82               0.85  0.11
>>        annotate-user-time               4.35               3.49  0.00
>>        annotate-wall-time              10.60              10.06  0.16

I don't know how to interpret these numbers. What tool did you run to
generate them? 

I need to get some profile data on running mtn over NFS; something is
deadly slow. Would this tool help with that?

--

-- 
-- Stephe
Markus Wanner | 23 Sep 18:21
Gravatar

Re: using empty() instead of size()

Hi,

Stephen Leake wrote:
> I don't know how to interpret these numbers. What tool did you run to
> generate them? 

It's the output of compare.py from the nvm.cbench branch, which takes
CSV inputs from the pythonic benchmark suite.

> I need to get some profile data on running mtn over NFS; something is
> deadly slow. Would this tool help with that?

You can certainly run benchmarks over NFS as well. Although I'm not sure
how helpful that is. You are already saying it's deadly slow. What
difference does a benchmark value make against real world experience?

Regards

Markus Wanner
Stephen Leake | 24 Sep 01:09
Favicon

Re: using empty() instead of size()

Markus Wanner <markus <at> bluegap.ch> writes:

> Hi,
>
> Stephen Leake wrote:
>> I don't know how to interpret these numbers. What tool did you run to
>> generate them? 
>
> It's the output of compare.py from the nvm.cbench branch, which takes
> CSV inputs from the pythonic benchmark suite.

Ok, thanks.

>> I need to get some profile data on running mtn over NFS; something is
>> deadly slow. Would this tool help with that?
>
> You can certainly run benchmarks over NFS as well. Although I'm not sure
> how helpful that is. You are already saying it's deadly slow. What
> difference does a benchmark value make against real world
> experience?

I need the profile info more than the total time; I want to find out
which particular function in mtn is slow. Then I want to add a ticker
output to it, so I will know it's not hung; then maybe speed it up
somehow.

The long term plan is to get rid of the NFS link, but we are stuck
with it for a while.

--

-- 
-- Stephe
Markus Wanner | 24 Sep 10:21
Gravatar

Re: using empty() instead of size()

Hi,

Stephen Leake wrote:
> I need the profile info more than the total time; I want to find out
> which particular function in mtn is slow. Then I want to add a ticker
> output to it, so I will know it's not hung; then maybe speed it up
> somehow.

Guessing you are on Linux, that sounds more like you should have a look
at oprofile and try the exact mtn actions you want profiling data for.

Regards

Markus Wanner
Jens Finkhäuser | 22 Sep 23:21
Favicon
Gravatar

Re: using empty() instead of size()

On Mon, Sep 22, 2008 at 02:14:25PM -0700, Zack Weinberg wrote:
> I'm honestly surprised .empty() and .size() == 0 don't generate
> identical code, but hey.  Thanks!
  Imagine a linked list implementation. Finding out whether the
pointer to the first element is NULL is simple, and enough to answer
whether the list is empty. Finding out the number of elements requires
traversing the list.

  Of course you can implement a linked list differently, but that'd be
how a very simple implementation might behave. At least some STL list
implementations behave in a similar fashion.

Jens

Gmane