473,503 Members | 2,098 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

"multiple putchar()'s" versus "collect chars in char-array and use puts()" - speed/efficiency

In terms of efficieny:

Is it better to use multiple putchar()'s after one another as one gets
to new char's

OR

is it better to collect the characters to a char-array first, and then
use puts() to print to screen
????

/******* ExampleA **********/
/**** collect chars and then call puts ****/

char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};

#define uchar2hex(char_ptr, str_ptr) \
*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]; \
*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]; \
*str_ptr++ = ' ';

{
int i;
char source[29] = "asdfasdfasdfasdfsadfasdfasdf";
char *src_ptr = source;
char dest[29];
char *dest_ptr = dest;

for (i = 0; i < 29; i++) {
uchar2hex(src_ptr, dest_ptr);
}
*dest_ptr = '\0';
puts(dest);
}

/********* ExampleB *************/
/***** putchar() as each new char is encountered ******/

char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};

#define uchar2hex2(char_ptr, str_ptr) \
putchar(*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]); \
putchar(*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]); \
putchar(*str_ptr++ = ' ');

{
int i;
char source[29] = "asdfasdfasdfasdfsadfasdfasdf";
char *src_ptr = source;
char dest[29];
char *dest_ptr = dest;

for (i = 0; i < 29; i++) {
uchar2hex2(src_ptr, dest_ptr);
}
*dest_ptr = '\0';
}

Oct 11 '07 #1
9 4071
On Oct 11, 2:54 am, anon.a...@gmail.com <<<Albert - forgot to sign the
root post>>wrote:
<snip>
char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};

#define uchar2hex(char_ptr, str_ptr) \
*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]; \
*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]; \
<snip>

Is there a faster way of converting a 8-bit char to its 2-digit hex
representation?

Regards,
Albert

Oct 11 '07 #2
an*******@gmail.com wrote:
In terms of efficieny:

Is it better to use multiple putchar()'s after one another as one gets
to new char's

OR

is it better to collect the characters to a char-array first, and then
use puts() to print to screen
The C Standard says next to nothing about efficiency, even
though "efficiency" is one of the principal reasons people turn
to C nowadays. However, in regard to the question you ask the
Standard, unusually, offers an unequivocal answer: "Yes!" (See
Section 6.5.14; see also http://www.c-faq.com/ Question 20.13.)

--
Eric Sosman
es*****@ieee-dot-org.invalid
Oct 11 '07 #3
On Oct 10, 9:10 pm, anon.a...@gmail.com wrote:
On Oct 11, 2:54 am, anon.a...@gmail.com <<<Albert - forgot to sign theroot post>>wrote:

<snip>
char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
#define uchar2hex(char_ptr, str_ptr) \
*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]; \
*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]; \

<snip>

Is there a faster way of converting a 8-bit char to its 2-digit hex
representation?
Well, you can do it without the global table. Though this probably
won't be faster, it ought not to be slower.

#define uchar2hex(P, S) do { \
*(P)++ = "0123456789ABCDEF"[(int)(unsigned char)*(S)]; \
*(P)++ = "0123456789ABCDEF"[(int)(unsigned char)*(S)++ & 0xF]; }
while (0)

Using a 256x2 table would probably be slightly faster.

char hex[][2] = { { '0', '0' }, ... };

#define uchar2hex(P, S) do { \
memcpy(P, hex[(int)(unsigned char)*(S)++], 2);
(P) += 2; } while (0)

especially if your compiler open codes the memcpy.
Oct 11 '07 #4
Gene <ge**********@gmail.comwrites:
On Oct 10, 9:10 pm, anon.a...@gmail.com wrote:
>On Oct 11, 2:54 am, anon.a...@gmail.com <<<Albert - forgot to sign theroot post>>wrote:

<snip>
char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
#define uchar2hex(char_ptr, str_ptr) \
*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]; \
*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]; \

<snip>

Is there a faster way of converting a 8-bit char to its 2-digit hex
representation?

Well, you can do it without the global table. Though this probably
won't be faster, it ought not to be slower.

#define uchar2hex(P, S) do { \
*(P)++ = "0123456789ABCDEF"[(int)(unsigned char)*(S)]; \
*(P)++ = "0123456789ABCDEF"[(int)(unsigned char)*(S)++ & 0xF]; }
while (0)

Using a 256x2 table would probably be slightly faster.

char hex[][2] = { { '0', '0' }, ... };

#define uchar2hex(P, S) do { \
memcpy(P, hex[(int)(unsigned char)*(S)++], 2);
(P) += 2; } while (0)

especially if your compiler open codes the memcpy.
The "do { ... } while (0)" trick is an improvement over the original
macro definition, since it allows it to be used in any statement
context. But since the macro definition consists entirely of
expressions, it's better to just define it as a single expression.

Re-writing the original macro (without changing what it does) yields:

#define uchar2hex(char_ptr, str_ptr) \
( *(str_ptr)++ = symbols[((unsigned char)*(char_ptr)) >4], \
*(str_ptr)++ = symbols[((unsigned char)*(char_ptr)++) & 0xF], \
*(str_ptr)++ = ' ' )

(The last line was lost in a quoting mishap.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 11 '07 #5
On Oct 11, 3:33 am, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
anon.a...@gmail.com wrote:
In terms of efficieny:
Is it better to use multiple putchar()'s after one another as one gets
to new char's
OR
is it better to collect the characters to a char-array first, and then
use puts() to print to screen

The C Standard says next to nothing about efficiency, even
though "efficiency" is one of the principal reasons people turn
to C nowadays. However, in regard to the question you ask the
Standard, unusually, offers an unequivocal answer: "Yes!"
"Yes" to the first part (use multiple putchar()'s) OR "yes" to the
second part (collect and use puts()) ???

I suspect you mean "yes" to the 2nd part, since there puts() works at
a low level and can hand multiple chunks to the driver routine which
outputs the text; whereas putchar() only hands one char at a time to
the driver - slowing thing down. -?
(See
Section 6.5.14; see alsohttp://www.c-faq.com/Question 20.13.)
I've had a look and fail to see how Section 6.5.14
http://c0x.coding-guidelines.com/6.5.14.html
http://www.open-std.org/jtc1/sc22/wg...4.pdf#page=101

is relevant.

-Albert
Oct 11 '07 #6
an*******@gmail.com wrote:
On Oct 11, 3:33 am, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
>anon.a...@gmail.com wrote:
>>In terms of efficieny:
Is it better to use multiple putchar()'s after one another as one gets
to new char's
OR
is it better to collect the characters to a char-array first, and then
use puts() to print to screen
The C Standard says next to nothing about efficiency, even
though "efficiency" is one of the principal reasons people turn
to C nowadays. However, in regard to the question you ask the
Standard, unusually, offers an unequivocal answer: "Yes!"

"Yes" to the first part (use multiple putchar()'s) OR "yes" to the
second part (collect and use puts()) ???
[...]
>(See
Section 6.5.14; see alsohttp://www.c-faq.com/Question 20.13.)

I've had a look and fail to see how Section 6.5.14
http://c0x.coding-guidelines.com/6.5.14.html
http://www.open-std.org/jtc1/sc22/wg...4.pdf#page=101

is relevant.
It describes the result of the logical OR operator.
In your case, the two propositions are opposites, so
their OR is true, hence "Yes!"

Once again, I commend Question 20.13 of the FAQ to
your attention.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Oct 11 '07 #7
an*******@gmail.com wrote:
>
On Oct 11, 3:33 am, Eric Sosman <esos...@ieee-dot-org.invalidwrote:
anon.a...@gmail.com wrote:
In terms of efficieny:
Is it better to use multiple putchar()'s after one another as one gets
to new char's
OR
is it better to collect the characters to a char-array first, and then
use puts() to print to screen
The C Standard says next to nothing about efficiency, even
though "efficiency" is one of the principal reasons people turn
to C nowadays. However, in regard to the question you ask the
Standard, unusually, offers an unequivocal answer: "Yes!"

"Yes" to the first part (use multiple putchar()'s) OR "yes" to the
second part (collect and use puts()) ???

I suspect you mean "yes" to the 2nd part, since there puts() works at
a low level and can hand multiple chunks to the driver routine which
outputs the text; whereas putchar() only hands one char at a time to
the driver - slowing thing down. -?
I suspect he meant "yes" to the entire statement. (As in, "yes,
either it will be more efficient to do the former, or it will be
more efficient to do the latter".) It was a way of saying there
is no firm "using this method will be more efficient in all
situations". In some cases, one will be "better", while in other
cases, that same one is "worse".
(See
Section 6.5.14; see alsohttp://www.c-faq.com/Question 20.13.)

I've had a look and fail to see how Section 6.5.14
http://c0x.coding-guidelines.com/6.5.14.html
http://www.open-std.org/jtc1/sc22/wg...4.pdf#page=101

is relevant.
6.5.14 describes the logical OR operator. The statement "A or B" is
true if either A or B is true. (You asked "is this better OR is that
better?" Since one of those must be true, "A or B" must be true.)

His reference to 6.5.14 confirms my original interpretation.

Consider that, to many programmers, "do you know what time it is"
requires a boolean response.

Consider that, to a computer, "give me a list of people who live in
New York and New Jersey" is likely to return a very short (if not
empty) list.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Oct 11 '07 #8
On Thu, 11 Oct 2007 00:54:36 -0000, an*******@gmail.com wrote:
>In terms of efficieny:

Is it better to use multiple putchar()'s after one another as one gets
to new char's

OR

is it better to collect the characters to a char-array first, and then
use puts() to print to screen
????
It depends on how your system implements I/O. The various byte output
functions are required to behave "as if" fputc was called for each
character.

If puts and putchar both actually do call fputc for each character and
if putchar is a macro, then

The putchar approach requires n calls to fputc.

The puts approach requires the same n calls + one call to puts
+ the effort to build the array.

putchar appears more efficient.

If puts does its own I/O in a single block and if function calls are
"expensive", then puts appears more efficient.

Unless you are doing a ton of I/O, it would be better(tm) to use the
approach that is more natural to whatever process you are performing.
The execution cost will be insignificant compared to future
maintenance costs when the program is updated.
>
/******* ExampleA **********/
/**** collect chars and then call puts ****/

char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};

#define uchar2hex(char_ptr, str_ptr) \
*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]; \
*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]; \
*str_ptr++ = ' ';

{
int i;
char source[29] = "asdfasdfasdfasdfsadfasdfasdf";
char *src_ptr = source;
char dest[29];
This is the wrong size for dest. Each input character requires three
output characters. Once i gets to 10, you will overflow this array
and enter the realm of undefined behavior.
char *dest_ptr = dest;

for (i = 0; i < 29; i++) {
uchar2hex(src_ptr, dest_ptr);
}
*dest_ptr = '\0';
puts(dest);
}

/********* ExampleB *************/
/***** putchar() as each new char is encountered ******/

char symbols[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};

#define uchar2hex2(char_ptr, str_ptr) \
putchar(*str_ptr++ = symbols[((unsigned char)*char_ptr) >4]); \
putchar(*str_ptr++ = symbols[((unsigned char)*char_ptr++) & 0xF]); \
putchar(*str_ptr++ = ' ');
Why are you storing the output characters anywhere?
>
{
int i;
char source[29] = "asdfasdfasdfasdfsadfasdfasdf";
char *src_ptr = source;
char dest[29];
Also too small.
char *dest_ptr = dest;

for (i = 0; i < 29; i++) {
uchar2hex2(src_ptr, dest_ptr);
}
*dest_ptr = '\0';
Since you output individual characters and not a string, why bother?
>}

Remove del for email
Oct 13 '07 #9
an*******@gmail.com wrote:
# In terms of efficieny:
#
# Is it better to use multiple putchar()'s after one another as one gets
# to new char's
#
# OR
#
# is it better to collect the characters to a char-array first, and then
# use puts() to print to screen
# ????

Whatever simplifies your code is best.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Haven't you ever heard the customer is always right?
Oct 19 '07 #10

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

Similar topics

19
6744
by: Christian Fowler | last post by:
I have a VERY LARGE pile of geographic data that I am importing into a database (db of choice is postgres, though may hop to oracle if necessary). The data is strictly hierarchical - each node has...
10
8249
by: copx | last post by:
I want to save a struct to disk.... as plain text. At the moment I do it with a function that just writes the data using fprintf. I mean like this: fprintf(fp, "%d %d", my_struct.a, my_struct.b)...
81
7221
by: Matt | last post by:
I have 2 questions: 1. strlen returns an unsigned (size_t) quantity. Why is an unsigned value more approprate than a signed value? Why is unsighned value less appropriate? 2. Would there...
2
4168
by: SunRise | last post by:
Hi I am creating a C Program , to extract only-Printable-characters from a file ( any type of file) and display them. OS: Windows-XP Ple help me to fix the Errors & Warnings and explain...
4
6043
by: C. J. Clegg | last post by:
A month or so ago I read a discussion about putting const ints in header files, and how one shouldn't put things in header files that allocate memory, etc. because they will generate multiple...
6
2728
by: varojee | last post by:
hi! can we use any function to display our input without using a " printf " function? does c support such this possibilities? ...
14
5652
by: mlw | last post by:
Do not take anything about this, it is not a flame or troll, while I'm not new to Java I favor C++. However, I may need to use it in a contract position, and am concerned that the restrictions it...
2
3838
by: Gabriela | last post by:
Hi, I would like to use VBScript regexp to locate multiple characters in a string and replace them with a single "-" char. In my case it's multiple "-" chars: E.g.:...
32
2056
by: vippstar | last post by:
Assuming all the values of int are in the range of unsigned char, what happends if getc returns EOF? Is it possible that EOF was the value of the byte read? Does that mean that code aiming for...
15
19914
by: Andreas Eibach | last post by:
.... but I have an unsigned long value in the printf. This warning came when I used gcc 4.x to compile. .... unsigned long offset = 0; .... Well OK, an "easy" way would be instead of printf...
0
7204
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
7091
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
7464
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5586
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,...
1
5018
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...
0
3171
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1516
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
741
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
391
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.