Will printf still have a cost even if I redirect output to /dev/null?
Clash Royale CLAN TAG#URR8PPP
We have a daemon that contains a lot of print messages. Since we are working on an embedded device with a weak CPU and other constraint hardware, we want to minimize any kinds of costs (IO, CPU, etc..) of printf messages in our final version. (Users don't have a console)
My teammate and I have a disagreement. He thinks we can just redirect everything to /dev/null. It won't cost any IO so affections will be minimal. But I think it will still cost CPU and we better define a macro for printf so we can rewrite "printf" (maybe just return).
So I need some opinions about who is right. Will Linux be smart enough to optimize printf? I really doubt it.
c linux performance embedded dev-null
|
show 7 more comments
We have a daemon that contains a lot of print messages. Since we are working on an embedded device with a weak CPU and other constraint hardware, we want to minimize any kinds of costs (IO, CPU, etc..) of printf messages in our final version. (Users don't have a console)
My teammate and I have a disagreement. He thinks we can just redirect everything to /dev/null. It won't cost any IO so affections will be minimal. But I think it will still cost CPU and we better define a macro for printf so we can rewrite "printf" (maybe just return).
So I need some opinions about who is right. Will Linux be smart enough to optimize printf? I really doubt it.
c linux performance embedded dev-null
18
Beware side effects:printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost
– pmg
Jan 15 at 9:42
4
Providing amyprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write
– msrd0
Jan 15 at 10:10
15
@pmg: Side-effects in aprintf
statement are evil. In code review, I'd definitely raise an issue over that.
– MSalters
Jan 15 at 14:37
8
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
4
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48
|
show 7 more comments
We have a daemon that contains a lot of print messages. Since we are working on an embedded device with a weak CPU and other constraint hardware, we want to minimize any kinds of costs (IO, CPU, etc..) of printf messages in our final version. (Users don't have a console)
My teammate and I have a disagreement. He thinks we can just redirect everything to /dev/null. It won't cost any IO so affections will be minimal. But I think it will still cost CPU and we better define a macro for printf so we can rewrite "printf" (maybe just return).
So I need some opinions about who is right. Will Linux be smart enough to optimize printf? I really doubt it.
c linux performance embedded dev-null
We have a daemon that contains a lot of print messages. Since we are working on an embedded device with a weak CPU and other constraint hardware, we want to minimize any kinds of costs (IO, CPU, etc..) of printf messages in our final version. (Users don't have a console)
My teammate and I have a disagreement. He thinks we can just redirect everything to /dev/null. It won't cost any IO so affections will be minimal. But I think it will still cost CPU and we better define a macro for printf so we can rewrite "printf" (maybe just return).
So I need some opinions about who is right. Will Linux be smart enough to optimize printf? I really doubt it.
c linux performance embedded dev-null
c linux performance embedded dev-null
edited Jan 16 at 13:55
iBug
20.5k63864
20.5k63864
asked Jan 15 at 9:40
Michael PengMichael Peng
438311
438311
18
Beware side effects:printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost
– pmg
Jan 15 at 9:42
4
Providing amyprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write
– msrd0
Jan 15 at 10:10
15
@pmg: Side-effects in aprintf
statement are evil. In code review, I'd definitely raise an issue over that.
– MSalters
Jan 15 at 14:37
8
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
4
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48
|
show 7 more comments
18
Beware side effects:printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost
– pmg
Jan 15 at 9:42
4
Providing amyprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write
– msrd0
Jan 15 at 10:10
15
@pmg: Side-effects in aprintf
statement are evil. In code review, I'd definitely raise an issue over that.
– MSalters
Jan 15 at 14:37
8
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
4
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48
18
18
Beware side effects:
printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost– pmg
Jan 15 at 9:42
Beware side effects:
printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost– pmg
Jan 15 at 9:42
4
4
Providing a
myprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write– msrd0
Jan 15 at 10:10
Providing a
myprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write– msrd0
Jan 15 at 10:10
15
15
@pmg: Side-effects in a
printf
statement are evil. In code review, I'd definitely raise an issue over that.– MSalters
Jan 15 at 14:37
@pmg: Side-effects in a
printf
statement are evil. In code review, I'd definitely raise an issue over that.– MSalters
Jan 15 at 14:37
8
8
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
4
4
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48
|
show 7 more comments
5 Answers
5
active
oldest
votes
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:34
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing awrite(2)
call to write stdout is forbidden by the standard.
– iBug
Jan 15 at 13:29
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
|
show 10 more comments
The printf
function will write to stdout
. It is not conforming to optimize for /dev/null
.
Therefore, you will have the overhead of parsing the format string and evaluating any necessary arguments, and you will have at least one syscall, plus you will copy a buffer to kernel address space (which, compared to the cost of the syscall is neglegible).
This answer is based on the specific documentation of POSIX.
System Interfaces
dprintf, fprintf, printf, snprintf, sprintf - print formatted output
The fprintf() function shall place output on the named output stream. The printf() function shall place output on the standard output stream stdout. The sprintf() function shall place output followed by the null byte, '', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available.
Base Definitions
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
|
show 4 more comments
The printf
function writes to stdout
. If the file descriptor connected to stdout
is redirected to /dev/null
then no output will be written anywhere (but it will still be written), but the call to printf
itself and the formatting it does will still happen.
1
@OP: Addition: You can further reduce the cost ofprintf()
by creating a new driver which provides a newFILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to/dev/null
goes away.
– glglgl
Jan 15 at 9:48
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:32
add a comment |
Write your own that wraps printf() using the printf() source as a guideline, and returning immediately if a noprint flag is set. The downside of this is when actually printing it will consume more resources because of having to parse the format string twice. But it uses negligible resources when not printing. Can't simply replace printf() because the underlying calls inside printf() can change with a newer version of the stdio library.
void printf2(const char *formatstring, ...);
5
If you usevprintf
insideprintf2
you will not have to parse the format string twice.
– zwol
Jan 15 at 21:29
add a comment |
Generally speaking, an implementation is permitted to perform such optimisations if they do not affect the observable (functional) outputs of the program. In the case of printf()
, that would mean that if the program doesn't use the return value, and if there are no %n
conversions, then the implementation would be allowed to do nothing.
In practice, I'm not aware of any implementation on Linux that currently (early 2019) performs such an optimisation - the compilers and libraries I'm familiar with will format the output and write the result to the null device, relying on the kernel' to ignore it.
You may want to write a forwarding function of your own if you really need to save the cost of formatting when the output is not used - you'll want to it to return void
, and you should check the format string for %n
. (You could use snprintf
with a NULL
and 0
buffer if you need those side-effects, but the savings are unlikely to repay the effort invested).
Since the observable behavior of the abstract machine includes calls to library I/O functions, surelyprintf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...
– jinawee
Jan 16 at 16:29
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54196197%2fwill-printf-still-have-a-cost-even-if-i-redirect-output-to-dev-null%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:34
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing awrite(2)
call to write stdout is forbidden by the standard.
– iBug
Jan 15 at 13:29
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
|
show 10 more comments
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:34
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing awrite(2)
call to write stdout is forbidden by the standard.
– iBug
Jan 15 at 13:29
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
|
show 10 more comments
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
edited Jan 17 at 11:44
Prakash Pazhanisamy
8681923
8681923
answered Jan 15 at 9:46
iBugiBug
20.5k63864
20.5k63864
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:34
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing awrite(2)
call to write stdout is forbidden by the standard.
– iBug
Jan 15 at 13:29
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
|
show 10 more comments
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:34
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing awrite(2)
call to write stdout is forbidden by the standard.
– iBug
Jan 15 at 13:29
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
28
28
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspect
stdout
, learn it is /dev/null, and suppress printf
calls that do not contain %n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).– Eric Postpischil
Jan 15 at 11:34
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspect
stdout
, learn it is /dev/null, and suppress printf
calls that do not contain %n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).– Eric Postpischil
Jan 15 at 11:34
1
1
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
@EricPostpischil Thanks for that! Very valuable information.
– iBug
Jan 15 at 11:39
7
7
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing a
write(2)
call to write stdout is forbidden by the standard.– iBug
Jan 15 at 13:29
@EricPostpischil See Damon's answer for reference from the POSIX standard - supressing a
write(2)
call to write stdout is forbidden by the standard.– iBug
Jan 15 at 13:29
4
4
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
AFAIK, console output is pretty slow so the time saved by writting to /dev/null could be significant. It would be less effective if you were writting to file, though.
– SJuan76
Jan 15 at 15:12
3
3
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
@SJuan76 Writing to a terminal isn't necessarily slow, displaying it is (i.e. depends on terminal).
– iBug
Jan 15 at 15:13
|
show 10 more comments
The printf
function will write to stdout
. It is not conforming to optimize for /dev/null
.
Therefore, you will have the overhead of parsing the format string and evaluating any necessary arguments, and you will have at least one syscall, plus you will copy a buffer to kernel address space (which, compared to the cost of the syscall is neglegible).
This answer is based on the specific documentation of POSIX.
System Interfaces
dprintf, fprintf, printf, snprintf, sprintf - print formatted output
The fprintf() function shall place output on the named output stream. The printf() function shall place output on the standard output stream stdout. The sprintf() function shall place output followed by the null byte, '', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available.
Base Definitions
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
|
show 4 more comments
The printf
function will write to stdout
. It is not conforming to optimize for /dev/null
.
Therefore, you will have the overhead of parsing the format string and evaluating any necessary arguments, and you will have at least one syscall, plus you will copy a buffer to kernel address space (which, compared to the cost of the syscall is neglegible).
This answer is based on the specific documentation of POSIX.
System Interfaces
dprintf, fprintf, printf, snprintf, sprintf - print formatted output
The fprintf() function shall place output on the named output stream. The printf() function shall place output on the standard output stream stdout. The sprintf() function shall place output followed by the null byte, '', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available.
Base Definitions
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
|
show 4 more comments
The printf
function will write to stdout
. It is not conforming to optimize for /dev/null
.
Therefore, you will have the overhead of parsing the format string and evaluating any necessary arguments, and you will have at least one syscall, plus you will copy a buffer to kernel address space (which, compared to the cost of the syscall is neglegible).
This answer is based on the specific documentation of POSIX.
System Interfaces
dprintf, fprintf, printf, snprintf, sprintf - print formatted output
The fprintf() function shall place output on the named output stream. The printf() function shall place output on the standard output stream stdout. The sprintf() function shall place output followed by the null byte, '', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available.
Base Definitions
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
The printf
function will write to stdout
. It is not conforming to optimize for /dev/null
.
Therefore, you will have the overhead of parsing the format string and evaluating any necessary arguments, and you will have at least one syscall, plus you will copy a buffer to kernel address space (which, compared to the cost of the syscall is neglegible).
This answer is based on the specific documentation of POSIX.
System Interfaces
dprintf, fprintf, printf, snprintf, sprintf - print formatted output
The fprintf() function shall place output on the named output stream. The printf() function shall place output on the standard output stream stdout. The sprintf() function shall place output followed by the null byte, '', in consecutive bytes starting at *s; it is the user's responsibility to ensure that enough space is available.
Base Definitions
shall
For an implementation that conforms to POSIX.1-2017, describes a feature or behavior that is mandatory. An application can rely on the existence of the feature or behavior.
answered Jan 15 at 13:17
DamonDamon
51.4k15100155
51.4k15100155
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
|
show 4 more comments
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
2
2
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
The kernel is responsible for copying the buffer to kernel address space, and the null driver probably omits that step (on Linux, it definitely does - it does not even check that it is a valid address)
– Random832
Jan 15 at 15:13
1
1
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
Maybe make it a bit clearer, that not every call to printf will result in a syscall - at the moment this is a bit ambiguous, otherwise great answer.
– Voo
Jan 15 at 19:46
11
11
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
-1, this ignores the as-if rule (which applies to the entire implementation, not just the compiler). If the implementation as a whole can prove that there is no difference in observable behavior, it can make any optimization it likes, even after compilation has completed. Now, if we were talking about a language other than C, you might be right.
– Kevin
Jan 15 at 19:47
4
4
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
@Kevin Does the as-if rule of the C standard apply to the POSIX standard too?
– Angew
Jan 16 at 12:31
1
1
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
@Kevin Since calls to I/O functions are observable behavior themselves, isn't optimization restricted. If the standard said that only I/O is observable effect, then removing printf to /dev/null would be possible.
– jinawee
Jan 16 at 16:34
|
show 4 more comments
The printf
function writes to stdout
. If the file descriptor connected to stdout
is redirected to /dev/null
then no output will be written anywhere (but it will still be written), but the call to printf
itself and the formatting it does will still happen.
1
@OP: Addition: You can further reduce the cost ofprintf()
by creating a new driver which provides a newFILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to/dev/null
goes away.
– glglgl
Jan 15 at 9:48
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:32
add a comment |
The printf
function writes to stdout
. If the file descriptor connected to stdout
is redirected to /dev/null
then no output will be written anywhere (but it will still be written), but the call to printf
itself and the formatting it does will still happen.
1
@OP: Addition: You can further reduce the cost ofprintf()
by creating a new driver which provides a newFILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to/dev/null
goes away.
– glglgl
Jan 15 at 9:48
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:32
add a comment |
The printf
function writes to stdout
. If the file descriptor connected to stdout
is redirected to /dev/null
then no output will be written anywhere (but it will still be written), but the call to printf
itself and the formatting it does will still happen.
The printf
function writes to stdout
. If the file descriptor connected to stdout
is redirected to /dev/null
then no output will be written anywhere (but it will still be written), but the call to printf
itself and the formatting it does will still happen.
edited Jan 15 at 10:20
answered Jan 15 at 9:42
Some programmer dudeSome programmer dude
298k25253415
298k25253415
1
@OP: Addition: You can further reduce the cost ofprintf()
by creating a new driver which provides a newFILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to/dev/null
goes away.
– glglgl
Jan 15 at 9:48
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:32
add a comment |
1
@OP: Addition: You can further reduce the cost ofprintf()
by creating a new driver which provides a newFILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to/dev/null
goes away.
– glglgl
Jan 15 at 9:48
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspectstdout
, learn it is /dev/null, and suppressprintf
calls that do not contain%n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).
– Eric Postpischil
Jan 15 at 11:32
1
1
@OP: Addition: You can further reduce the cost of
printf()
by creating a new driver which provides a new FILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to /dev/null
goes away.– glglgl
Jan 15 at 9:48
@OP: Addition: You can further reduce the cost of
printf()
by creating a new driver which provides a new FILE *
(depending on if your platform supports that). In this case, you can create a data sink which discards the data. The cost for formatting etc. still remains, but the OS call for writing to /dev/null
goes away.– glglgl
Jan 15 at 9:48
2
2
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspect
stdout
, learn it is /dev/null, and suppress printf
calls that do not contain %n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).– Eric Postpischil
Jan 15 at 11:32
Answers like this should state they are based on general understanding of common implementations and not upon specific documentation. In theory, there is no reason a C implementation might not inspect
stdout
, learn it is /dev/null, and suppress printf
calls that do not contain %n
and whose return value is not used. We cannot really assert nobody has done this, and students ought to learn the provenance of information since an important part of engineering is knowing how you know something (is it specified in a standard, is it just assumed, is it provable, and so on).– Eric Postpischil
Jan 15 at 11:32
add a comment |
Write your own that wraps printf() using the printf() source as a guideline, and returning immediately if a noprint flag is set. The downside of this is when actually printing it will consume more resources because of having to parse the format string twice. But it uses negligible resources when not printing. Can't simply replace printf() because the underlying calls inside printf() can change with a newer version of the stdio library.
void printf2(const char *formatstring, ...);
5
If you usevprintf
insideprintf2
you will not have to parse the format string twice.
– zwol
Jan 15 at 21:29
add a comment |
Write your own that wraps printf() using the printf() source as a guideline, and returning immediately if a noprint flag is set. The downside of this is when actually printing it will consume more resources because of having to parse the format string twice. But it uses negligible resources when not printing. Can't simply replace printf() because the underlying calls inside printf() can change with a newer version of the stdio library.
void printf2(const char *formatstring, ...);
5
If you usevprintf
insideprintf2
you will not have to parse the format string twice.
– zwol
Jan 15 at 21:29
add a comment |
Write your own that wraps printf() using the printf() source as a guideline, and returning immediately if a noprint flag is set. The downside of this is when actually printing it will consume more resources because of having to parse the format string twice. But it uses negligible resources when not printing. Can't simply replace printf() because the underlying calls inside printf() can change with a newer version of the stdio library.
void printf2(const char *formatstring, ...);
Write your own that wraps printf() using the printf() source as a guideline, and returning immediately if a noprint flag is set. The downside of this is when actually printing it will consume more resources because of having to parse the format string twice. But it uses negligible resources when not printing. Can't simply replace printf() because the underlying calls inside printf() can change with a newer version of the stdio library.
void printf2(const char *formatstring, ...);
edited Jan 15 at 18:56
answered Jan 15 at 17:43
MAXdBMAXdB
414
414
5
If you usevprintf
insideprintf2
you will not have to parse the format string twice.
– zwol
Jan 15 at 21:29
add a comment |
5
If you usevprintf
insideprintf2
you will not have to parse the format string twice.
– zwol
Jan 15 at 21:29
5
5
If you use
vprintf
inside printf2
you will not have to parse the format string twice.– zwol
Jan 15 at 21:29
If you use
vprintf
inside printf2
you will not have to parse the format string twice.– zwol
Jan 15 at 21:29
add a comment |
Generally speaking, an implementation is permitted to perform such optimisations if they do not affect the observable (functional) outputs of the program. In the case of printf()
, that would mean that if the program doesn't use the return value, and if there are no %n
conversions, then the implementation would be allowed to do nothing.
In practice, I'm not aware of any implementation on Linux that currently (early 2019) performs such an optimisation - the compilers and libraries I'm familiar with will format the output and write the result to the null device, relying on the kernel' to ignore it.
You may want to write a forwarding function of your own if you really need to save the cost of formatting when the output is not used - you'll want to it to return void
, and you should check the format string for %n
. (You could use snprintf
with a NULL
and 0
buffer if you need those side-effects, but the savings are unlikely to repay the effort invested).
Since the observable behavior of the abstract machine includes calls to library I/O functions, surelyprintf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...
– jinawee
Jan 16 at 16:29
add a comment |
Generally speaking, an implementation is permitted to perform such optimisations if they do not affect the observable (functional) outputs of the program. In the case of printf()
, that would mean that if the program doesn't use the return value, and if there are no %n
conversions, then the implementation would be allowed to do nothing.
In practice, I'm not aware of any implementation on Linux that currently (early 2019) performs such an optimisation - the compilers and libraries I'm familiar with will format the output and write the result to the null device, relying on the kernel' to ignore it.
You may want to write a forwarding function of your own if you really need to save the cost of formatting when the output is not used - you'll want to it to return void
, and you should check the format string for %n
. (You could use snprintf
with a NULL
and 0
buffer if you need those side-effects, but the savings are unlikely to repay the effort invested).
Since the observable behavior of the abstract machine includes calls to library I/O functions, surelyprintf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...
– jinawee
Jan 16 at 16:29
add a comment |
Generally speaking, an implementation is permitted to perform such optimisations if they do not affect the observable (functional) outputs of the program. In the case of printf()
, that would mean that if the program doesn't use the return value, and if there are no %n
conversions, then the implementation would be allowed to do nothing.
In practice, I'm not aware of any implementation on Linux that currently (early 2019) performs such an optimisation - the compilers and libraries I'm familiar with will format the output and write the result to the null device, relying on the kernel' to ignore it.
You may want to write a forwarding function of your own if you really need to save the cost of formatting when the output is not used - you'll want to it to return void
, and you should check the format string for %n
. (You could use snprintf
with a NULL
and 0
buffer if you need those side-effects, but the savings are unlikely to repay the effort invested).
Generally speaking, an implementation is permitted to perform such optimisations if they do not affect the observable (functional) outputs of the program. In the case of printf()
, that would mean that if the program doesn't use the return value, and if there are no %n
conversions, then the implementation would be allowed to do nothing.
In practice, I'm not aware of any implementation on Linux that currently (early 2019) performs such an optimisation - the compilers and libraries I'm familiar with will format the output and write the result to the null device, relying on the kernel' to ignore it.
You may want to write a forwarding function of your own if you really need to save the cost of formatting when the output is not used - you'll want to it to return void
, and you should check the format string for %n
. (You could use snprintf
with a NULL
and 0
buffer if you need those side-effects, but the savings are unlikely to repay the effort invested).
answered Jan 15 at 13:15
Toby SpeightToby Speight
16.7k134165
16.7k134165
Since the observable behavior of the abstract machine includes calls to library I/O functions, surelyprintf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...
– jinawee
Jan 16 at 16:29
add a comment |
Since the observable behavior of the abstract machine includes calls to library I/O functions, surelyprintf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...
– jinawee
Jan 16 at 16:29
Since the observable behavior of the abstract machine includes calls to library I/O functions, surely
printf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...– jinawee
Jan 16 at 16:29
Since the observable behavior of the abstract machine includes calls to library I/O functions, surely
printf
at least it would have to be called right? Although I'm not sure how two different calls to a library function are considered different or not...– jinawee
Jan 16 at 16:29
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54196197%2fwill-printf-still-have-a-cost-even-if-i-redirect-output-to-dev-null%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
18
Beware side effects:
printf("%d", x=a+b);
If you redirect to /dev/null side effects will happen; if you rewrite as a do nothing macro, side effects will be lost– pmg
Jan 15 at 9:42
4
Providing a
myprintf(...) return;
is probably what you want. You can then have a macro for printf forwarding to that method, preserving side effects yet not formatting any string or calling write– msrd0
Jan 15 at 10:10
15
@pmg: Side-effects in a
printf
statement are evil. In code review, I'd definitely raise an issue over that.– MSalters
Jan 15 at 14:37
8
I would take a step back. In a Linux daemon there are far better options then printf... Consider for example using syslog instead, if you set the log level at startup (ideally from an environment variable) and you can direct the logs to file or to another machine over the network trivially, and the log level allows you to turn off the logging of things you don't care about at relatively low cost in execution time. Even better if you do something like trapping a few signals you can arrange to change the log level at runtime without stopping, much less having to recompile the daemon.
– Dan Mills
Jan 15 at 19:33
4
Seems like you need a proper logging framework. At the minimum, one that supports lazy evaluation of the message.
– Alexander
Jan 15 at 23:48