Tuesday, September 29, 2009

comp.lang.c++ - 10 new messages in 5 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* about new and delete - 4 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/85fc26a34c7b73d3?hl=en
* Why doesn't the default argument allow const member? - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/5b4659040c4a93de?hl=en
* A few questions about singletons... - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/dd7f3af258a800cd?hl=en
* RVO - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/a41ed66263ac91f0?hl=en
* Pass a pointer variable to a function accept reference - 1 messages, 1
author
http://groups.google.com/group/comp.lang.c++/t/330170d81fae3d1c?hl=en

==============================================================================
TOPIC: about new and delete
http://groups.google.com/group/comp.lang.c++/t/85fc26a34c7b73d3?hl=en
==============================================================================

== 1 of 4 ==
Date: Mon, Sep 28 2009 3:41 pm
From: Sam


Joshua Maurice writes:

> On Sep 28, 4:05 am, Sam <s...@email-scan.com> wrote:
>>
>> > In case you missed it Sam, I'd like to know your reply to this simple
>> > argument: If it's a small number of items, performance doesn't matter,
>>
>> To you, may be not. But in latency-sensitive environments, it most certainly
>> does.
>>
>> But just keep thinking that it doesn't matter, don't let me discourage you
>> otherwise. I consider stuff like that to be excellent job security.
>
> You are the one picking and choosing data to fit your arguments, often
> in an inconsistent matter. If it's all about a user entering numbers
> at a terminal, there is no latency to speak of.

You asked for my "reply to this simple" theoretical argument, and you got
one. Suddenly, you want to switch from this theoretical situation to a
practical one, involving terminal entry. This is the only way you can
continue to flounder -- by cherry picking bits from all over place, and
discarding all other, inconvenient facts.

> So, try to be
> consistent: either we're discussing the OP's use case exactly, as you
> sometimes claim, or we're discussing general practice, as you just
> claimed.

Hillarous -- you can't even make up your mind, yourself!

>
> If the program is not being used at an interactive terminal, such as
> piping the output of one program to it, and the number of ints is ~30
> or more, then std::vector will noticeably outperform.

Furthermore, as I already stated previously in the thread, just because the
penalty of one's favorite security blanket is negligible, it does not
mandate its use.

Your position is so untenable, that you keep going back and revisiting
arguments that have been answered.

> I don't know of any real use cases which require std::list over
> std::vector because of this "magical latency".

Well, just because you don't, it doesn't mean that they do not exist.

> std::list only
> outperforms std::vector by a unmeasurable amount when the number of

This "unmeasurable amount" is very much measurable. And, many people work
very hard, and get paid a lot of money, to squeeze every last bit of latency
they can, out of their realtime apps. The extra 20 or so milliseconds of
latency, that I showed, often means being either in the black, or in the
red, at the end of the day.

>> > but if it's a large number of elements, then std::vector will
>> > outperform std::list.
>>
>> Only in some situations involving a large number of elements. In others, a
>> std::vector cannot be used for other reasons, so it's not even an option.
>
> Again, stay consistent. Either we're addressing the user's original
> use case on performance grounds, or we're talking about general
> practice.

Here's a pop quiz. Who's arguing the merits of the containers in question by
arguing what happens when you put a lot more objects in the container than
in OP's case?

Ain't me.

> Frankly, your arguments are inane. "Oh, it doesn't fit this
> use case which I'm keeping in my bag, so we should just use
> std::list".

> std::vector is better for the OP's use case. Give me

Facts disagree. I posted hard data that proves otherwise. Numbers don't lie.
In OP's case, std::list is faster. And, it's not my fault that the hard data
pierces the bubble you've wrapped yourself in.

>> >                        So, for a small number of elements the choice
>> > does not matter, so he should use vector to make his code reusable and
>> > extensible, because as we all know code is frequently reused, such as
>>
>> If one places code reusability at a premium, one should be using iterators,
>> rather than any std::vector-specific methods, or overloads. As I showed,
>> doing so allows one to substitute the underlying implementation, without
>> changing the code.
>>
>> A completely different issue.
>
> It is inane to say "Oh, but your algorithm must be as general as
> possible".

Newflash: a well-designed algorithm implementation that will not require any
changes in the event that the underlying container implementation changes,
is "inane".

Just another new thing one learns every day, around here.


> There is little to nothing to be gained by templatizing the
> algorithm in this case. I cannot think of a situation where I would
> take his original algorithm and replace vector with list, thus there
> is no value in templatizing it, but there is a cost associated with
> templatizing it, so I will not.

Just because you can't think of one, it doesn't prevent it from ever
happening, and from having to deal with the consequences. I think you just
don't have enough real world experience to understand the value of deploying
an implementation that will require a lot less testing, when something like
this happens.

… Whoa. It turns out that I'm quite familiar with your so-called "unified
enterprise data integration platform" product, and its overall quality. I
must say, that this is quite an eye opener, and puts your arguments, and
your overall position, in a new light.

>> > This was, and is, the source of contention for one issue, that you
>> > claim performance is a reason to use list, but that's only true for a
>> > very small number of inserts, your interpretation of his use case.
>>
>> Not just "interpretation". I showed the actual numbers.
>
> Please consider actually reading what others post. I said "your
> interpretation of his use case is a small number of inserts". Measured
> numbers of execution time of programs does not come into it.

I see. Measuring the execution time of programs with alternative
implementations will not, I repeat, will NOT, tell anyone anything about
which implemention is the more efficient one.

Brilliant.

>> cannot measure the difference for his program for a small input set.
>> You can however measure the difference for a larger input set, in
>> which case std::vector clearly wins.)
>
> You did not measure the difference in his use case. For his use case,
> the difference in speed between std::list and std::vector is entirely
> unmeasurable for ~10 elements.

I measured it. Repeatedly. And easily. The fact that you don't seem to place
much value in anything that does not involve some "unified enterprise data
integration platform" does not invalidate my results.

> The various other costs of process
> spawning, program start up and death, waiting for the user to type
> things, etc., will entirely dwarf the time spent in list vs vector.
> You cannot accurately measure it.

It may be a shocking revelation to some, but fork() and exec() will take the
same amount time for a simple program that uses either std::list or a
std::vector. Therefore, subtracting the fixed startup overhead from the
sampled execution times will only serve to increase the proportional
performance penalty of std::vector compared to std::list. Ask an eighth
grader for help, if you can't figure out how this works.

> However, for larger inputs, the
> difference is measurable,

Really? Would you be kind and refresh my memory with who you claim always
fails to make up his mind whether "Either we're addressing the user's
original use case on performance grounds, or we're talking about general
practice."

Physician, heal thyself.

>> Sorry, facts disagree.
>
> You sir are an idiot or a troll. I shall wash my hands of this thread,
> and of you forever.

Although I can assure you that I share a reciprocal opinions of you, I will
not call you an idiot or a troll. I'll let the facts present themselves, and
paint an equivalent picture, as the inescapable conclusion.

== 2 of 4 ==
Date: Mon, Sep 28 2009 3:44 pm
From: Sam


Richard Herring writes:

> In message <cone.1254136305.452816.10312.500@commodore.email-scan.com>,
> Sam <sam@email-scan.com> writes
>
>>If there's even one non-inlined function call in the body of the loop,
>>there are only a very limited amount of cases where the compiler will
>>know that the function call cannot possibly modify the container using
>>some other pointer or reference, elsewhere, and it is safe to optimize
>>out the ending iterator evaluation on every iteration. Otherwise, each
>>function call can potentially modify the container, and since each
>>iteration compares against the value of end() that exists at that time,
>>it cannot be optimized out.
>
> So the saving is something like one load, or similar, per iteration,
> _if_ the loop body is complex enough to contain a non-inline function
> call. What's that as a fraction of the overall execution time?

Whatever it is, I wouldn't consider it something to be ignored. Always
producing the best possible code is a good habit to have. As I mentioned
elsewhere, in certain situations, a difference of a few milliseconds in
latency of production code means whether you come out in the black, or in
the red, at the end of the day.

But, I suppose, if you're not doing anything particularly important, and you
don't care, you shouldn't. If you forget the whole thing, but this suddenly
becomes important enough for someone to care about it, it won't be you.


== 3 of 4 ==
Date: Mon, Sep 28 2009 4:13 pm
From: Sam


Juha Nieminen writes:

> Sam wrote:
>>> std::list uses more memory and more allocations than std::vector does.
>>
>> Very funny. You're a real comedian, you should be writing for SNL.
>>
>> You've got your blinders on, and can't see all the additional memory
>> std::vector allocates, in order to reserve room for the growth of a
>> vector. There are plenty of situations where std::vector uses more
>> memory than std::list would, with the same number of elements.
>>
>> Your blanket, absolute statement is evidence that you do not fully
>> understand the subject matter at hand.
>
> Unlike you, I actually *measure* things, rather than relying to
> theoretical handwaving.
>
> For example, I measured the memory usage of a program which does this:

Ok, so you've agreed to measure a theoretical use case.

> std::vector<int> v;
> for(int i = 0; i < 1000000; ++i) v.push_back(i);
>
> The amount of memory taken by the program was 4.77 MB. Then I changed
> the std::vector to std::list and ran the test again. The memory taken by
> the program was 16 MB.

Well, I decided to measure an equally valid theoretical use case, only
slightly different from yours. Even more list elements, and an even larger
objects, not just a puny int.

std::list<foo> v;

for(int i = 0; i < 1100000; ++i) v.push_back(foo());

ps -l showed:

0 S 500 3660 3587 11 80 0 - 45904 hrtime pts/0 00:00:00 t

45904 pages=179 megabytes of RAM.

After replacing the std::list with a std::vector:

0 S 500 3648 3587 58 80 0 - 68476 hrtime pts/0 00:00:01 t

68476 pages=267 megabytes of RAM.

This is just as valid measurement as yours. Sorry to have to confuse you
with facts.

Your homework assignment is to figure out how big the foo class is. It's not
very big at all.

>> I am merely pointing out situations where std::list is a better choice,
>> in response to illogical claims about the superiority of std::vector in
>> all possible situations.
>
> Exactly who claimed that std::vector is superior in all possible
> situations? The only thing that I, or anyone else I have seen, have
> claimed is that std::vector is superior in *this* particular situation.

This particular situation: .

Hint: you need a magnifying class to see it.

> Using iterators might be more *generic*, but that's not the same thing
> as being *simpler*.

Damn right. If the underlying container changes, it's easier to rewrite a
bunch of code, then just to have it Just Work™.


> When measuring all possible factors in this particular situation,
> std::deque comes out as a clear winner in all counts (including speed,
> which was your original argument, and std::deque wins by a huge margin).

No, it does not. deque shares many negative factors with vector.

> Clearly std::list is *not* the best solution in this particular situation.

If by "this" you mean your test case, where your element count is just below
the reserve capacity of a vector that uses logarithmic expansion, then it
is.

If by *this* you mean OP's original situation, it is not the best solution.
Nor it would be when your real world case doesn't happen to have the same
stars aligned so nicely, when your container's size will jump all over that
place.


>> If the OP was trying to
>> do something else, such as reading the input data from a file, where the
>> potential number of elements might be quite large; or if the OP wanted
>> to sort the elements, for example, that would've called for a different
>> approach.
>
> Just out of curiosity: Why wouldn't std::list be feasible for sorting
> the elements? std::list does have a O(n log n) sorting function. (And if
> the elements were very large and heavy to copy, then it could even beat
> std::sort applied to a std::vector.)

"sort" not necessary = std::sort().


== 4 of 4 ==
Date: Mon, Sep 28 2009 4:24 pm
From: Sam


Juha Nieminen writes:

>> And what is the complexity of removing an element from the middle of the
>> list, versus the middle of a vector?
>
> O(n) for both.

Hahahahahaha.

std::list<obj> theList;

// …

std::list<obj>::iterator p;

// …

theList.erase(p); // Warning, O(n)!!!!!

Very funny.

> If you want to prove me wrong, write a function which
> takes a std::list as parameter and removes the element at the exact
> middle faster than O(n).

What you fail to grok, is that when you have a member of containe that you
want removed, you already have its iterator, you don't need to search for
it.

Thank you for playing.

> And if you don't specify that the *order* of the elements must be
> maintained (as you never did), then removing the middle element from a
> vector becomes O(1) (by assigning the last element to it and then
> shrinking the vector by one). Removing it from a std::list is still O(n).

You're just grasping at straws here, desperately trying to create a
contrived situation that fits your preconceived notions. This is something
that will often occur inside ivory halls of academia, where brownie points
are awarded for completing a purely theoretical excersize that bears no
relevance to anything that will occur in practice.

>> additional memory requirements of std::vector?
>
> Unlike you, I have actually *measured* in practice the memory usage of
> std::vector vs. std::list.

… only in a cherry-picked case.

>> But as long as anyone makes the absurd, blanket statement that using a
>> vector is always the right solution
>
> Could you please quote me from the post where I said that using a
> vector is *always* the right solution? Or anyone else, for that matter.

Well, how about the "Unlike you, I have actually *measured* in practice the
memory usage of std::vector vs. std::list" part, referring to your argument
that std::vector always wins?


>> I'll wait.
>
> The topic was "what is the best data container for this particular
> situation". Exactly how is suggesting std::deque "changing the subject"?
>
> Hey, I could nitpick about *you* changing the topic. Who was the first
> one to bring up inserting in the middle of a container? I'll wait.

Who was the first one to start yammering about huge lists and vectors, to
start off this entire thread?

I'll wait.


>>> std::deque is a practical demonstration of why std::list is not the
>>> best choice.
>>
>> Sorry to confuse you with facts, but std::deque suffers the same
>> limitations as std::vector, in terms of the complexity of insertion or
>> deletion in the middle of the container, as well as the same memory
>> usage issue.
>
> See? Look who is changing the topic.

The individual who first brought up dequeue. Hint: it wasn't me.

> Your original argument was that
> std::list is the fastest (if you suffer from dementia, please refer back
> to your own posts). Clearly that's not true.

Clearly it was true, /in OP's original use case/. Nothing you've said
disputes it.

"fastest" != "always fastest". Elementary, my dear Watson, elementary.

> Besides, as I said, inserting and deleting from the middle of a list
> is O(n).

No, it's not. See 23.2.2.3:

Complexity: Insertion of a single element into a list takes constant time
and exactly one call to the copy constructor of T.

Complexity: Erasing a single element is a constant time operation with a
single call to the destructor of T.

No qualification about inserting into/deleting from the beginning, the end,
or into the middle. It's always constant. Sorry to confuse you with facts.

> If you want to prove me wrong, give the function which takes a
> std::list and removes the mid element faster than O(n).

list.erase(q);

HTH.


==============================================================================
TOPIC: Why doesn't the default argument allow const member?
http://groups.google.com/group/comp.lang.c++/t/5b4659040c4a93de?hl=en
==============================================================================

== 1 of 2 ==
Date: Mon, Sep 28 2009 4:42 pm
From: Daniel Pitts


Francesco S. Carta wrote:
> On 21 Set, 11:53, Divick <divick.kish...@gmail.com> wrote:
>> Hi,
>>
>> I have the following code (see below). My compiler g++ 3.4.6 doesn't
>> compile it. I wonder why shouldn't this be allowed? I understand that
>> const int a, would be different for different objects, unlike static
>> const. And functions are common for all objects. But from the
>> compiler's perspective, shouldn't it be simple to handle as for every
>> invocation of a function with default argument, if the value is not
>> supplied then the compiler can simply initialize the function with the
>> value on which the function has been called?
>>
>> class x
>> {
>> private :
>> const int a;
>> public :
>> X() : a(1)
>> {}
>>
>> void foo(int arg = a)
>> {
>> cout << arg << endl;
>> }
>>
>> };
>>
>> Thanks in advance,
>> -DK
>
> If I got it right, members functions aren't much different from normal
> functions, that is, you should think of your "foo(int)" as something
> like "foo(int, A* this)", because the function itself is not aware of
> the object it is called upon and needs the "hidden 'this' argument" to
> be aware of it.
>
> Unfortunately you cannot even write something like "void foo(int arg =
> this->a)", because the 'this' pointer is visible only inside of the
> function's body.
>
> If you need a workaround, one way could be to decide a range of values
> that lead to use the const value, such as:
> -------
> class A {
> const int i;
> public:
> A(int v = 0) : i(v) {}
> int foo(int v = -1) {
> if(v < 0) {
> return i;
> } else {
> return v;
> }
> }
> };
> -------
Or a different work around:

void foo(int arg) {
std::cout << arg << std::endl;
}
void foo() {
foo(a);
}

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>


== 2 of 2 ==
Date: Mon, Sep 28 2009 4:53 pm
From: "Francesco S. Carta"


On 29 Set, 01:42, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> Francesco S. Carta wrote:
> > On 21 Set, 11:53, Divick <divick.kish...@gmail.com> wrote:
> >> Hi,
>
> >> I have the following code (see below). My compiler g++ 3.4.6 doesn't
> >> compile it. I wonder why shouldn't this be allowed? I understand that
> >> const int a, would be different for different objects, unlike static
> >> const. And functions are common for all objects. But from the
> >> compiler's perspective, shouldn't it be simple to handle as for every
> >> invocation of a function with default argument, if the value is not
> >> supplied then the compiler can simply initialize the function with the
> >> value on which the function has been called?
>
> >> class x
> >> {
> >> private :
> >>        const int a;
> >> public :
> >>        X() : a(1)
> >>        {}
>
> >>        void foo(int arg = a)
> >>        {
> >>                cout << arg << endl;
> >>        }
>
> >> };
>
> >> Thanks in advance,
> >> -DK
>
> > If I got it right, members functions aren't much different from normal
> > functions, that is, you should think of your "foo(int)" as something
> > like "foo(int, A* this)", because the function itself is not aware of
> > the object it is called upon and needs the "hidden 'this' argument" to
> > be aware of it.
>
> > Unfortunately you cannot even write something like "void foo(int arg =
> > this->a)", because the 'this' pointer is visible only inside of the
> > function's body.
>
> > If you need a workaround, one way could be to decide a range of values
> > that lead to use the const value, such as:
> > -------
> > class A {
> >   const int i;
> >   public:
> >   A(int v = 0) : i(v) {}
> >   int foo(int v = -1) {
> >     if(v < 0) {
> >       return i;
> >     } else {
> >       return v;
> >     }
> >   }
> > };
> > -------
>
> Or a different work around:
>
> void foo(int arg) {
>     std::cout << arg << std::endl;}
>
> void foo() {
>    foo(a);
>
> }

Right, thanks, but that has already been pointed out and acknowledged.

Follow the threads thoroughly please.

Have good time,
Francesco
--
Francesco S. Carta, hobbyist
http://fscode.altervista.org

==============================================================================
TOPIC: A few questions about singletons...
http://groups.google.com/group/comp.lang.c++/t/dd7f3af258a800cd?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Sep 28 2009 5:31 pm
From: "Chris M. Thomasson"


"James Kanze" <james.kanze@gmail.com> wrote in message
news:dcf6fb5f-3e7a-4938-8a06-308660297961@f10g2000vbf.googlegroups.com...
> On Sep 28, 2:37 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
>> "Joshua Maurice" <joshuamaur...@gmail.com> wrote in message
> [...]
>> > Short version: Actually doing a correct singleton in C++ is
>> > hard (tm).
>
>> IMVHO, it sure as heck simplifies things if your program is
>> single-threaded or you guarantee that no threads will ever be
>> created before `main()'!!!
>
> Yes. Except that you can extend it a little: you have to
> guarantee that no threads which use the singleton will ever be
> created before main. That's an important difference---when
> third party libraries are involved, you can't make many
> guarantees concerning what happens before main.

That is a very good point James.

Thanks.


> (Sybase, for
> example, does start threads from the constructors of static
> objects, at least in some configurations.) On the other hand,
> it's a pretty good bet that those libraries don't use a
> singleton that you write.

==============================================================================
TOPIC: RVO
http://groups.google.com/group/comp.lang.c++/t/a41ed66263ac91f0?hl=en
==============================================================================

== 1 of 2 ==
Date: Mon, Sep 28 2009 10:53 pm
From: Gareth Owen


As I think I understand it, RVO requires a hidden parameter.

Assuming that the call has access to the declaration, and not the
definition, how can the compiler possibly know whether the compilation
of the function used RVO, and thus whether to pass a hidden argument
to facilitate RVO.

That being the case, is RVO possible in library functions?


== 2 of 2 ==
Date: Mon, Sep 28 2009 11:07 pm
From: "Alf P. Steinbach"


* Gareth Owen:
> As I think I understand it, RVO requires a hidden parameter.

Yes.


> Assuming that the call has access to the declaration, and not the
> definition, how can the compiler possibly know whether the compilation
> of the function used RVO, and thus whether to pass a hidden argument
> to facilitate RVO.

In practice it simply has some internal rule about which routines will use a
hidden result pointer argument. At least that's how MSVC and g++ do it.

It's not a big deal.

Either the return value is so small that it fits in registers, in which case
there's no need for RVO, or it doesn't fit in registers, in which case a hidden
argument is usually passed anyway (an alternative could be to pass the result on
the machine stack, but I have never seen or heard about that being done).


> That being the case, is RVO possible in library functions?

Yes.


Cheers & hth.,

- Alf

==============================================================================
TOPIC: Pass a pointer variable to a function accept reference
http://groups.google.com/group/comp.lang.c++/t/330170d81fae3d1c?hl=en
==============================================================================

== 1 of 1 ==
Date: Mon, Sep 28 2009 11:33 pm
From: "Louis"


Hi all:

Im having a little bit confuse of passing a pointer variable to a function
that accept reference:

void test(int &temp)
{

temp+= temp + 2;

cout << "function:" << temp << endl;
cout << "function:" << &temp << endl; //c:0x22ff1c
}

int main(int argc, char *argv[])
{

int c = 0;
int *d = &c;
cout << "d:" << *d << endl;
test(*d); // i guess, *d is dereference of d, which is value of c, and
same as int &temp = c, like passing reference?
cout << "c:" << &c << endl; //function:0x22ff1c,
return 0;
}

it works, i guess, *d is dereference of d, which is value of c, and same as
int &temp = c, like passing reference?

In the above code i'm trying to pass a dereference pointer d, which is
contain value of c, can anyone can explain to me if this is a good way to
pass a pointer variable?

Many Thanks

L

==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: