강의 컨설팅 트레이닝 무료진단 무료책자 마케팅편지 마케팅정보공유 다이어리 서비스제휴 고객센터

시스템콜인 open 계열 함수와 스트림기반의 fopen 계열..
작성자 : 13 김영철
등록날짜 : 2009.01.13 14:50
1,221
시스템콜인 open과 write를 이용한 파일열기, 쓰기와 스트림기반의 fopen, fputc, fputs 를 이용한 파일열기/쓰기를 비교해보았다.

시스템콜함수들은 사용자코드 프로세싱 도중에 커널영역함수를 호출하고 다시 돌아가므로 비용이 꽤 든다고 볼수 있으나 그 코드자체는 매우 최적화되어 있을것이다. 또한 스트림기반의 함수는 glibc에서 버퍼를 이용하여 처리하므로 작은크기를 많이 쓸때는 분명히 이것이 훨씬 더 빠를것이라는 예상이 된다. 궁금한점은 큰 크기를 한번에 쓸때도 과연 어느것이 더 빠를가 하는것이 되겠다.

먼저 1byte의 데이터를 1M까지 쓰기한다

open-1.c

#include <stdio.h>
#include <sys/types.h>

#include <fcntl.h>


#define FILE_SIZE 1024 * 1000

int main()
{
    int i;
    int fp = open("open.txt", O_CREAT | O_TRUNC | O_WRONLY);
    for (i = 0; i < FILE_SIZE; i++)
    {
         write(fp, "A", 1);
    }
}


<테스트 결과>
real 0m5.187s
user 0m0.519s
sys 0m4.011s


fopen-1.c
#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>


#define FILE_SIZE 1024 * 1000

int main()
{
    int i;
    FILE* fp;
    fp = fopen("fopen.txt", "w+");
    for (i = 0; i < FILE_SIZE; i++)
    {
         fputc('A', fp);
    }
}


<테스트 결과>
real 0m0.119s
user 0m0.054s
sys 0m0.010s


두번째론 1M의 데이터를 한번에 쓴다

open-2.c
#include <stdio.h>
#include <sys/types.h>

#include <fcntl.h>


#define FILE_SIZE 1024 * 1000

int main()
{
    int i;
    int fp = open("open.txt", O_CREAT | O_TRUNC | O_WRONLY);
    char buff[FILE_SIZE];
    memset(buff, 'A', FILE_SIZE);
    write(fp, buff, FILE_SIZE);
}


<테스트 결과>
real 0m0.058s
user 0m0.001s
sys 0m0.010s


fopen-2.c
#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>


#define FILE_SIZE 1024 * 1000

int main()
{
    int i;
    char buff[FILE_SIZE];
    FILE* fp;
    memset(buff, 'A', FILE_SIZE - 1);
    buff[FILE_SIZE] = '\0';
    fp = fopen("fopen.txt", "w+");
    fputs(buff, fp);
}


<테스트 결과>
real 0m0.029s
user 0m0.002s
sys 0m0.011s


time은 몇번재서 평균을 보았으나 귀찮아서 여긴 한번한것만 올린다. 시스템호출은 거의 일정한 time을 보여주는데 반해 스트림기반의 함수는 테스트할때마다 약간씩의 차이가 났다. 아무래도 버퍼기반이므로 상황따라 조금씩 차이가 나는듯하다.

결론적으로 적은데이트를 자주쓸땐 버퍼기반이 필요하며 이것은 소켓의 경우에도 마찬가지일터이다. 두번째 테스트에선 write의 user/sys타임이 조금더 빠른것을(거의같은) 알수잇겠다.

1024 바이트씩 쓰기 테스트

1024 바이트씩 1024 * 100 번을 쓰는 테스트를 해보았다.

#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>


#define FILE_SIZE 1024 * 100

int main()
{
    int i = 0;
    char buff[1024];
    FILE* fp;
    memset(buff, 'A', 1024);
    buff[1024] = '\n';
    fp = fopen("fopen.txt", "w+");

    while(i < FILE_SIZE)
    {
         fputs(buff, fp); 
         i++;
     }
}

<테스트 결과>
real 0m3.491s
user 0m0.250s
sys 0m0.570s


다음은 open버젼이다.
#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>


#define FILE_SIZE 1024 * 100

int main()
{
    int i = 0;
    char buff[1024];
    int fd;

    memset(buff, 'A', 1024);
    buff[1024] = '\n'; 
    fd = open("open.txt", O_CREAT|O_WRONLY|O_CREAT);
    while(i < FILE_SIZE)
    {
         write(fd, buff, 1024);
         i++;
    }
}


<테스트 결과>
real 0m3.124s
user 0m0.060s
sys 0m0.990s

결과를 확인해 보면 open이 미세? 하게 더 빠른 듯 하다. 그런데, 저 차이를 과연 미세하다고 해야할지 결정하기가 좀 애매모호하다.

fopen은 사용자레벨에서 버퍼를 관리하는 함수 답게 user시간을 꽤나 많이 잡아 먹고 있다는걸 확인할 수 있다.

혹시 fopen으로 열수 있는 파일객체의 수에 제한이 있을 까 해서 오픈 테스트를 해보았다.

#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>


#define FILE_SIZE 1024 * 100

int main()
{
    int i = 0; 
    char buff[1024];
    FILE* fp;
    memset(buff, 'A', 1024);
    buff[1024] = '\n';

    while( i < 2048)
    {
         fp = fopen("fopen.txt", "w+");
         if (fp == NULL)
         {
             perror("error");
             exit(0);
         }
         printf("%d\n", i);
         i++;
    }
}

테스트 결과 1020이 나왔는데, 프로세스 생성되는 0, 1, 2를 감안한다면 1024로 open과 동일함을 확인할 수 있었다.

언뜻 봤을때 open()계열과 fopen()계열은 그리 큰 성능상의 차이가 없고. 어떤 경우에는 fopen이 더 나은 성능을 보장해주고 있다. 그렇다면 open()과 fopen() 둘중 어느것을 사용할런지는 순전히 개발자의 기호에 의존하는가 ? 반드시 그렇다고 볼 수 없다. fopen() 계열의 함수는 재진입불가 함수다. 이 말은 멀티 쓰레드 프로그램에서의 사용이나 비동기적 사건을 다루어야 하는 프로그램에서 사용될 경우 문제가 될 소지가 있음을 의미한다. 이 점만을 유의한다면 어느 함수를 쓰건 별 차이는 없을 것으로 생각된다.

 
"쇼핑몰·홈페이지·오픈마켓
블로그·페이스북·이메일 등의 각종 마케팅 글쓰기,
각종 광고, 영업, 판매, 제안서, 전단지
반응율 3배×10배 이상 높이는 마법의 8단계 공식"
자세히보기

Comments

번호 제목 글쓴이 날짜 조회
3285 URL Cache를 사용하여 웹을 더욱 빠르게 13 김영철 01.13 980
3284 php5 99 단국강토 01.02 1055
3283 php 세션css 99 단국강토 12.30 1066
3282 [hatelove님의 JBBS 알고리즘 강좌 9] 13 김영철 01.14 1070
3281 reset , foreach 13 김영철 01.13 1106
3280 png 99 단국강토 12.30 1120
3279 플래시로 만든 php 함수 사전 13 김영철 01.13 1162
3278 PHP강좌】PHP URL함수 13 김영철 01.13 1167
3277 foreach 와 배열 13 김영철 01.14 1173
3276 주화면의 최신글을 preload로 빠르게 13 김영철 01.13 1184
3275 [php] 내장함수 13 김영철 01.13 1189
3274 태그 허용 함수???? 이제 개념을 바꾸자 13 김영철 01.14 1206
3273 플래쉬 Panels 에 대한 기본개념들 99 단국강토 01.06 1213
3272 파일관련함수 13 김영철 01.13 1213
3271 foreach 13 김영철 01.13 1214
3270 [hatelove님의 JBBS 알고리즘 강좌 7] 13 김영철 01.14 1216
3269 PHP도 객체지향형 프로그램이다..!!(클래스,상속동...) 13 김영철 01.13 1216
3268 PHP입문 - 함수 13 김영철 01.13 1216
3267 플래시에서 pc cam 영상보여주기 99 단국강토 02.16 1219
3266 php기본함수 정리!! 13 김영철 01.13 1220
열람중 시스템콜인 open 계열 함수와 스트림기반의 fopen 계열.. 13 김영철 01.13 1222
3264 소스를 간편하게 만들어 주는 with문 99 단국강토 02.10 1225
3263 객체 정의하기[이론,예제] 99 단국강토 01.29 1230
3262 php 파일 업, 다운로드 13 김영철 01.13 1232
3261 역인덱스 게시판 | 13 김영철 01.14 1242
3260 파일업로드 썸네일 제작 class 13 김영철 01.13 1245
3259 초보자용 이것저것 몇가지 팁 13 김영철 01.14 1247
3258 간단 날짜계산 99 단국강토 02.16 1249
3257 window 객체 M 최고의하루 12.20 1250
3256 디렉토리 폴더 모든파일 표시 [php] 13 김영철 01.14 1250
마케팅
특별 마케팅자료
다운로드 마케팅자료
창업,경영
기획,카피,상품전략
동기부여,성취