473,402 Members | 2,053 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

From bool to int: 1 or 0


If I wanted a super-efficient algorithm for counting the amount of 6's in
an array, (given the address of the first element and the amount of
elements), I might start off with:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
if( *p++ == 6 ) ++amount;
}
while ( p != p_over );

return amount;
}
However, by my own coding style, I'd probably change the loop to:

do
{
amount += (*p++ == 6);
} while ( p != p_over );
This would rely on the bool to int conversion which would yield 1 or 0.

Any thoughts on which would be likely to be more efficient on the
majority of architectures if I was writing fully portable code to be used
on everything from a wristwatch to a personal computer?


--

Frederick Gotham
Jun 16 '06 #1
16 2669
Frederick Gotham wrote:
If I wanted a super-efficient algorithm for counting the amount of
6's in an array, (given the address of the first element and the
amount of elements), I might start off with:
Or you might use 'std::count'...

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
if( *p++ == 6 ) ++amount;
}
while ( p != p_over );

return amount;
}
However, by my own coding style, I'd probably change the loop to:

do
{
amount += (*p++ == 6);
} while ( p != p_over );
Why bother when there is 'std::count'? :-)
This would rely on the bool to int conversion which would yield 1 or
0.
It does.
Any thoughts on which would be likely to be more efficient on the
majority of architectures if I was writing fully portable code to be
used on everything from a wristwatch to a personal computer?


return std::count(p, p + len, 6)

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '06 #2
Victor Bazarov posted:

return std::count(p, p + len, 6)

Thanks for the input, Victor. Checking for the quantity of instances of a
particular elemental value was just an example.

The main point of my post was to discuss which of the following two
approaches would be preferable in everyday programming:

if( *p++ == 6 ) ++amount;

or:

amount += (*p++ == 6);

--

Frederick Gotham
Jun 16 '06 #3
Frederick Gotham wrote:
Victor Bazarov posted:

return std::count(p, p + len, 6)

Thanks for the input, Victor. Checking for the quantity of instances of a
particular elemental value was just an example.

The main point of my post was to discuss which of the following two
approaches would be preferable in everyday programming:

if( *p++ == 6 ) ++amount;

or:

amount += (*p++ == 6);


In an effort to say what you mean I prefer the former; it says exactly
what is intended. The later is more cryptic and full of trickery. The
fact that you have to ask only proves the point.

Jun 16 '06 #4
Frederick Gotham wrote:
The main point of my post was to discuss which of the following two
approaches would be preferable in everyday programming:

if( *p++ == 6 ) ++amount;

or:

amount += (*p++ == 6);


I would say the former since it is more readable and likely of
negligible performance difference. The meaning of the first is obvious
even to a junior programmer, while one must decode the second, and
programmers have enough to worry about without trying to determine if
an unnecessarily clever statement like that is causing problems.

Cheers! --M

Jun 16 '06 #5

In response to both Noah and mlimber,

I am not at all bothered with whether one form is easier to understand
than the other -- I am solely concerned with performance.

If I wanted to simplify it, I could write a macro or a template function.

I suppose I could rephrase my question as follows:

Which of the following two macros would be preferable (performance-wise)
for use in portable code?:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }
#define IncrementIfTrue(amount,true_or_false)\
{ if ( true_or_false ) ++amount; }
To be used as follows:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
IncrementIfTrue( amount, *p++ == 6 );
}
while ( p != p_over );

return amount;
}
--
Frederick Gotham
Jun 16 '06 #6
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }

I must admit that I'm slightly unsure as to whether this will be as
efficient as I think it will. I wonder if the compiler would treat it
something like:

#define IncrementIfTrue(amount,true_or_false)\
{ amount += ( true_or_false ? 1 : 0 ); }
This might even be more costly than a simple "if" statment... Would it?

--

Frederick Gotham
Jun 16 '06 #7
Frederick Gotham wrote:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }

I must admit that I'm slightly unsure as to whether this will be as
efficient as I think it will. I wonder if the compiler would treat it
something like:

#define IncrementIfTrue(amount,true_or_false)\
{ amount += ( true_or_false ? 1 : 0 ); }
This might even be more costly than a simple "if" statment... Would
it?


Might. Or might not. If you are "solely concerned with performance",
measure it, don't guess. However, I bet that when the entire program
is measured, the difference between the two methods is going to be
negligible.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 16 '06 #8
Frederick Gotham wrote:
In response to both Noah and mlimber,

I am not at all bothered with whether one form is easier to understand
than the other -- I am solely concerned with performance.
Different compilers (and optimizers!) will produce different code, and
some CPU architectures and memory/cache configurations may do some
things more efficiently than others. So there's really no way to
determine which is faster in general. You could use a profiler on your
particular system to see which is faster on that system, but I strongly
suspect you're barking up the old "premature optimization" tree (see,
e.g., "Beware Premature Optimization" in
http://www.gotw.ca/publications/mill09.htm).

If I wanted to simplify it, I could write a macro or a template function.

I suppose I could rephrase my question as follows:

Which of the following two macros would be preferable (performance-wise)
for use in portable code?:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }
#define IncrementIfTrue(amount,true_or_false)\
{ if ( true_or_false ) ++amount; }
To be used as follows:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
IncrementIfTrue( amount, *p++ == 6 );
}
while ( p != p_over );

return amount;
}


First of all, macros should be avoided when possible because of all
their "issues" (see
http://www.parashift.com/c++-faq-lit....html#faq-9.5).

Second, using a macro or inline function or your clever code here just
obfuscates your meaning again. Write code for humans, not the CPU (let
the compiler/optimizer worry about that!), until you have measured (not
intuited!) that hand optimizing would be of significant benefit.

Cheers! --M

Jun 16 '06 #9

Frederick Gotham wrote:
In response to both Noah and mlimber,

I am not at all bothered with whether one form is easier to understand
than the other -- I am solely concerned with performance.
http://www.flounder.com/optimization.htm
http://en.wikipedia.org/wiki/Optimiz...en_to_optimize

Since you are asking about the performance of these different methods I
must assume you have NOT gathered data yet.
Which of the following two macros would be preferable (performance-wise)
for use in portable code?:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }
#define IncrementIfTrue(amount,true_or_false)\
{ if ( true_or_false ) ++amount; }


Without data I can only guess. My guess is on the later. Reasons:

* In the former the addition is always performed.
* The former requires the loading and addition of two registers, the
later does not.
* The former requires a cast.
* The former requires an additional assignment.

Now, the compiler could eliminate all those differences. The compiler
will have an easier time figuring out how to optimize when the code is
easier to interpret. The compiler was written by a human, therefor
things a human finds easier to interpret are more likely programmed
into the compiler's logic.

Stop trying to second guess your compiler before you even start.
Chances are very high that you are not smarter than the people that
wrote it. By trying to outwhit the experts you are more likely than
not to hinder the compiler's ability to optimize for you.

Jun 16 '06 #10
Noah Roberts wrote:
Which of the following two macros would be preferable (performance-wise)
for use in portable code?:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }
#define IncrementIfTrue(amount,true_or_false)\
{ if ( true_or_false ) ++amount; }


Without data I can only guess. My guess is on the later. Reasons:


I made a quick test program and tried it with different optimization
settings etc.
"if( *p++ == 6 ) ++amount;" was pretty much consistantly FASTER than
"amount += (*p++ == 6);". And It's significantly more readable as well.

This backs up Noah's intuition.

However, I agree with everybody here that the original poster needs to
measure HIS program first and then figure out which one is faster and
if improvements are necessary.

Though I'd add that profiling the whole program will very likely
conclude that this particular comparison isn't the biggest bottleneck
in the program anyways ;).

Cheers,
Andre

Jun 16 '06 #11
Frederick Gotham wrote:
If I wanted a super-efficient algorithm for counting the amount of 6's in
an array, (given the address of the first element and the amount of
elements), I might start off with:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
if( *p++ == 6 ) ++amount;
}
while ( p != p_over );

return amount;
}
However, by my own coding style, I'd probably change the loop to:

do
{
amount += (*p++ == 6);
} while ( p != p_over );
This would rely on the bool to int conversion which would yield 1 or 0.

Any thoughts on which would be likely to be more efficient on the
majority of architectures if I was writing fully portable code to be used
on everything from a wristwatch to a personal computer?


Here is the result on an AMD64 PC with gcc 4.1.1

version 1:

..L2:
movl (%rdi), %eax
addq $4, %rdi
cmpl $6, %eax
sete %al
movzbl %al, %eax
addl %eax, %edx
cmpq %rdi, %rcx
jne .L2
movl %edx, %eax
ret

version 2:

..L2:
xorl %eax, %eax
cmpl $6, (%rdi)
sete %al
addq $4, %rdi
addl %eax, %edx
cmpq %rdi, %rcx
jne .L2
movl %edx, %eax
ret

Seems that version 2 saves one instruction. Now you just have to check all
the other compiler and platform combinations and you are set :)

Jun 16 '06 #12
Noah Roberts <ro**********@gmail.com> wrote:
Frederick Gotham wrote:
Which of the following two macros would be preferable (performance-wise)
for use in portable code?:
#define IncrementIfTrue(amount,true_or_false)\
{ amount += static_cast<bool>( true_or_false ); }
#define IncrementIfTrue(amount,true_or_false)\
{ if ( true_or_false ) ++amount; }


Without data I can only guess. My guess is on the later. Reasons:

* In the former the addition is always performed.
* The former requires the loading and addition of two registers, the
later does not.
* The former requires a cast.
* The former requires an additional assignment.


Hypothetically speaking, an argument against the second version is that
the if test can cause the processor to stall if it doesn't have good
branch prediction capabilities, and it is possible that this could be
slower than performing all the extra instructions every time.

Of course I agree that the only real measure is to profile, and to code
for correctness and clarity first.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 16 '06 #13

Markus Schoder wrote:
Frederick Gotham wrote:
If I wanted a super-efficient algorithm for counting the amount of 6's in
an array, (given the address of the first element and the amount of
elements), I might start off with:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
if( *p++ == 6 ) ++amount;
}
while ( p != p_over );

return amount;
}
However, by my own coding style, I'd probably change the loop to:

do
{
amount += (*p++ == 6);
} while ( p != p_over );
This would rely on the bool to int conversion which would yield 1 or 0.

Any thoughts on which would be likely to be more efficient on the
majority of architectures if I was writing fully portable code to be used
on everything from a wristwatch to a personal computer?


Here is the result on an AMD64 PC with gcc 4.1.1

version 1:

.L2:
movl (%rdi), %eax
addq $4, %rdi
cmpl $6, %eax
sete %al
movzbl %al, %eax
addl %eax, %edx
cmpq %rdi, %rcx
jne .L2
movl %edx, %eax
ret

version 2:

.L2:
xorl %eax, %eax
cmpl $6, (%rdi)
sete %al
addq $4, %rdi
addl %eax, %edx
cmpq %rdi, %rcx
jne .L2
movl %edx, %eax
ret

Seems that version 2 saves one instruction. Now you just have to check all
the other compiler and platform combinations and you are set :)


Don't forget to try all the optimization flags, too! (You had also
better set up regression tests for when new versions/service packs for
compilers are released.)

Cheers! --M

Jun 16 '06 #14
Frederick Gotham wrote:
Victor Bazarov posted:

return std::count(p, p + len, 6)

Thanks for the input, Victor. Checking for the quantity of instances of a
particular elemental value was just an example.

The main point of my post was to discuss which of the following two
approaches would be preferable in everyday programming:

if( *p++ == 6 ) ++amount;

or:

amount += (*p++ == 6);



If performance is the sole concern, you might equally well worry about a
temporary produced by p++.

Jun 16 '06 #15
Frederick Gotham <fg*******@SPAM.com> wrote:
The main point of my post was to discuss which of the following two
approaches would be preferable in everyday programming:

if( *p++ == 6 ) ++amount;

or:

amount += (*p++ == 6);


If you turn on all optimization and they're not the same,
then something is amiss.

In any case, if it's important you will have to measure
the run-time, rather than relying on a belief as to
which is faster.

Steve
Jun 16 '06 #16

"Frederick Gotham" <fg*******@SPAM.com> wrote in message
news:Xn***************************@194.125.133.14. ..

If I wanted a super-efficient algorithm for counting the amount of 6's in
an array, (given the address of the first element and the amount of
elements), I might start off with:

#include <cstddef>

unsigned AmountSixes( const int *p, std::size_t const len )
{
unsigned amount = 0;

const T* const p_over = array + len;

do
{
if( *p++ == 6 ) ++amount;
}
while ( p != p_over );

return amount;
}
However, by my own coding style, I'd probably change the loop to:

do
{
amount += (*p++ == 6);
} while ( p != p_over );
This would rely on the bool to int conversion which would yield 1 or 0.

Any thoughts on which would be likely to be more efficient on the
majority of architectures if I was writing fully portable code to be used
on everything from a wristwatch to a personal computer?


Why don't you just test?

Output of following program for me is:
Start:62 End:93 Difference:31
Start:109 End:187 Difference:78

It made no difference to either if value was 0 or 6.

although with only 1 million iterations the values come out to 0. Meaning
this is trivial and you shouldn't even worry about it anyway. clock() on my
system returns values in milliseconds. Meaning that ten million iterations
takes 31 milliseconds, or .031 of a second. Divide that by 10 million each
assignment and test is taking 0.0000000031 of a second for the fastest,
0.0000000078 of a second for the slower. Is something that is going to take
you 0.0000000047 of a second more really enough to worry about optimizing?
Especially since your optimization makes it slower.

#include <iostream>
#include <string>
#include <time.h>

int main ( void )
{
time_t Start;
time_t End;

int value = 0;

int amount = 0;
Start = clock();

for ( int i = 1; i < 10000000; ++i )
{
if ( value == 6 )
++amount;
}

End = clock();

std::cout << "Start:" << Start << " End:" << End << " Difference:" <<
End - Start << std::endl;

amount = 0;
Start = clock();

for ( int i = 1; i < 10000000; ++i )
{
amount += ( value == 6 );
}

End = clock();

std::cout << "Start:" << Start << " End:" << End << " Difference:" <<
End - Start << std::endl;

std::string wait;
std::cin >> wait;
}
Jun 17 '06 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Doug | last post by:
I am working on an existing .NET (C Sharp) component that had a com interface that was used by a VB component. When it was originally written, it had the SSEAssemblyCom class below - minus the two...
0
by: Jacek | last post by:
Hi If it is wrong newsgroup, please let me know where to find the answer. I am trying to get item text form ListView (there are few items and 5 columns) from other application (application written...
3
by: Pierre Espenan | last post by:
A have a long integer class. The built integer type within a conditional statement returns bool false for int i=0 and bool true for any other non zero value. I want my long integer class to have...
4
by: Nomak | last post by:
Hello, With this code: $ cat -n ifs.cc 1 #include <vector> 2 #include <iostream> 3 4 using std::vector; 5 using std::cin;
1
by: =steFF= | last post by:
Hi, I am trying to print the values I have in a vector and my compiler says: error C2227: left of '->printLn' must point to class/struct/union on this instruction: m_data->printLn(); (in my file...
0
by: Jim dunn | last post by:
HI I am having problems with C# with regards to its compatibility with win32 API methods, I am trying to read from a windows CE comm port using C# and imported methods from coredll.dll, it seems...
2
by: David | last post by:
hello... how can i use IActiveDesktop COM interface from shell32.dll? thanx...
9
by: John Howard | last post by:
How can I read a text file that is on a UNIX server in VB.Net? Please keep it simple. Thanks, John
7
by: John.NET | last post by:
Hi, First please forgive that this is a repost as the first time I didn't have my proper nospam email configured... I'm writing a web service where one method will launch another .NET program...
12
by: Howard Swope | last post by:
This problem has been bugging me for a while. I have created a collection class and implemented it in a C# library. If I inherit from this class in another C# assembly and it works, but if I...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.