printf 수행시간에 대해서.

hurtak의 이미지

안녕하세요?
오래간만에 글을 올립니다.

프로그램을 짜다가, printf와 puts와 fprintf 등등 여러가지 출력문에 대해서 수행시간이 궁금해서 질문을 올리게 되었습니다.

저같은 경우에 수치해석 프로그램을 사용하는데, 그 프로그램에서 일정한 시간이 지날 때마다, 화면상에 현재 처리되고 있는 부분을 출력해 줍니다.
제가 알기로는 출력하는 부분이 가변인자에 의한 호출이기 때문에 그 절차가 복잡하다고 알고 있습니다.
학교 다닐 때 짰던 프로그램에서도 printf문을 넣었다가 뺐을 때, 코드의 수행시간 획기적으로 줄었던 것으로 기억합니다.
여기에 대해서 명확하게 아시는 분 답변 좀 주세요.

그리고, 하드디스크에 기록하는것(fprintf or fputs)나 모니터에 기록하는 것(printf or puts) 둘 중에서 어떤 것이 더 수행시간이 짧은지도 알고 싶습니다.

happyjun의 이미지

확인하는 가장 좋은 방법은 당연하지만 해당 시스템에서 직접 측정해 보는 것입니다.

라이브러리 구현 방법이나 파일 시스템에 따라 다를 수 있고, 출력하려는 내용에 따라 다를 수 있습니다.

clock_gettime()을 이용하시면 됩니다.

----------------------------------------
http://moim.at
http://mkhq.co.kr

hwandori의 이미지

파일로 출력하는것이 콘솔(모니터)에 출력하는것보다는 빠를겁니다..

asiawide의 이미지

심심할때 한번씩 찍어주는 정도라면 printf 나 fprintf 나 별로 차이가 없는데 루프 안에서 출력하거나 하면 속도가 눈에 띄게 차이가 납니다. fprintf 가 느리죠.

서지훈의 이미지

기본적으로 printf() 계열은 포맷에 맞게 파싱을 하는 부분이 들어 가기 때문에 그 비용이 만만치 않습니다.
아직저도 테스트는 안해봤지만 그냥 생각을 해도, 들어온 값을 그대로 쏟아내는 puts() 계열 보다 printf()가 많을듯 합니다.
그리고 "practical C" 에서도 printf()계열이 가장 많은 비용을 든다고 나와 있습니다.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

서지훈의 이미지

asiawide wrote:
심심할때 한번씩 찍어주는 정도라면 printf 나 fprintf 나 별로 차이가 없는데 루프 안에서 출력하거나 하면 속도가 눈에 띄게 차이가 납니다. fprintf 가 느리죠.

fprintf()를 할 때 어디에다가 쏟아 내는지도 많은 영향을 주게 됩니다.
stdout, stderr, file pointer, ... (buffer의 차이)
이들 각가이 틀리기 때문인데, fprintf()는 이것들을 편하게 출력을 해주는 정도로 보시면은 될듯 하군요.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

doldori의 이미지

수치해석용 코드라면 수치 계산이 실행 시간의 대부분을 차지할 텐데 출력 속도를
걱정하시는 것이 좀 묘하긴 합니다만...

hurtak wrote:
학교 다닐 때 짰던 프로그램에서도 printf문을 넣었다가 뺐을 때, 코드의 수행시간 획기적으로 줄었던 것으로 기억합니다.

이것은 아마 printf()의 속도라기보다는 화면에 스크롤되는 속도 때문일 것 같습니다.
보통 디스크 출력이 콘솔 출력보다 훨씬 빠르기 때문에 output redirection을
쓰셨다면 상당히 다른 결과를 보였을 겁니다.

asiawide wrote:
심심할때 한번씩 찍어주는 정도라면 printf 나 fprintf 나 별로 차이가 없는데 루프 안에서 출력하거나 하면 속도가 눈에 띄게 차이가 납니다. fprintf 가 느리죠.

그런가요? 예전에도 비슷한 얘기가 나왔긴 합니다만...
dopesoul의 이미지

printf 에 대한 맹목적 신뢰때문에 피보는 경우가 많습니다 ^^
꾸준히 버전업이 되고있는 함수이기도 하고, 버그가 많고 보안에대한
위협도 없지않아 있는 실정이죠.
직접 소스를 보세요. 그게 가장 확실할듯 싶습니다.

임베디드쪽 프로그래밍을 맡고있는 저로써는 믿을만한 printf 함수를
새로 제작하여 쓰고있습니다. 가장 확실하니까 ^^

익명 사용자의 이미지

doldori wrote:
수치해석용 코드라면 수치 계산이 실행 시간의 대부분을 차지할 텐데 출력 속도를
걱정하시는 것이 좀 묘하긴 합니다만...

그렇긴 합니다만, 7시간씩 30대 정도되는 시스템이 돌아가는데, 계속해서 화면에다가 찍어냅니다. 제가 프로그래밍쪽을 안 본지가 오래되서 잘 기억이 안 납니다만, Frame Buffer에다가 출력하는 함수를 호출하고서, 응답이 올 때까지 CPU에서 기다리고 있는 것 아닙니까?

속도를 빠르게 해 주는 방법으로 커널모드로 컴파일해서 커널에 포함시키는 것도 생각해 봤는데, 어느정도 능률이 있을지는 의문입니다.

fprintf(stderr, "hi");
printf("hi");
fprintf(fp, "hi");

time으로 측정해 본 결과 3번째 케이스는 거의 시간을 안 차지하고, 1,2번경우는 비슷하게 차지 했습니다.

pynoos의 이미지

수치 계산은 기본적으로 시스템콜 (man page 2 번)에 있는 것들은 거의 활용하지 않는 것들입니다. 그러나 printf는 write 를 내부적으로 사용하기 때문에 시스템콜을 수반하게 됩니다.

어떤 로그도 남기지 않고 공유 메모리에 쓰고 다른쪽에서 퍼가는 것이 가장 빠르겠지요.

두번째로, write를 수반하게 되면, 그 대상이 파일이냐 네트웍이냐(block, non-block)에 따라 속도차이가 확연하게 나타납니다. 상상에 맡겨도 그 차이는 확연히 알 수 있을 것입니다.

printf, write를 네트웍으로 하게 되면 기본적으로 blocking socket을 사용하므로 수치계산보다 로그를 남기는데 더 시간을 소비할 수도 있습니다.

hurtak의 이미지

와우!! 영광입니다.

pynoos wrote:
어떤 로그도 남기지 않고 공유 메모리에 쓰고 다른쪽에서 퍼가는 것이 가장 빠르겠지요.

대략, 계산을 하는 host에는 연산하고 그 결과는 메모리 위에다가 올려둔 다음에, 데이터가 처리되는 것이 필요할 때만 가져가서 쓰는 그런 식의 시스템을 말씀하시는 겁니까?

다른 쪽에서 퍼간다는 말의 의미를 잘 이해 못하겠습니다.

PS.개인적으로는 IPC같은 복잡한 방법은 절대로 못할 것 같아서, 램디스크를 구현해서, 거기 위에다가 관련 파일 시스템을 만들고, 마지막에 전송해 주도록 하는 것을 생각하고 있습니다.

-_- _-_ -_-

ssehoony의 이미지

printf 는 위에 말씀하셨던 것 처럼 화면 출력 처리 문제로 느려집니다.
printf 에서 포멧팅 하는 것만 따지만 꽤 빠르기 때문에 심각하게 고민할 필요가 없을 듯 합니다.
fprintf 로 파일에 기록하거나 sprintf 로 만들 결과물을 fwrite 로 파일에 기록하는 등의 방법은 생각보다 빠르게 반응합니다. 이유는 대부분 OS에서 지원해주는 디스크 캐시 때문이죠.
그리고 디스크 I/O 가 느리다고는 하지만 fprintf 로 1분안에 2기가 로그를 쌓는건 요즘 컴퓨터에서는 무지 쉬운일이지요. ( 이 이상의 포퍼먼스를 요구하시는건 아니겠죠? )
많은 양의 로그를 출력할때 화면 출력 처리 시간이 대부분이지 printf 의 포멧팅 시간이 아닙니다.
파일로 로그를 기록하고 tail 같은 툴로 로그를 계속 지켜 보는 방법이 쉽게 구현이 가능하면서 꽤 괜찮은 방법이 아닐까 합니다.

ㅡ,.ㅡ;;의 이미지

printf 의 수행시간때문에 걱정할일은 아마도 아닐가능성이 큽니다.
일단 printf 때문에 고민할경우는 매우빈번히 호출될때 문제입니다.즉, 루프내의 매우짧은 수행과정내부에 printf 를 넣는경우..
만일 출력물이 1초에 한번출력되는것이라면 printf 때문에 걱정할필요 없을듯
그렇지않고 굉장히 자주호출하는것이라면 자주호출안하도록 하세요.
그렇지도 않고 화면에 궂이 다뿌리겠다면..그건억집니다.ㅡ,.ㅡ;;
눈으로 다보지도 못할꺼니까요..


----------------------------------------------------------------------------

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.