[C/C++] stdio vs iostream

pikamon·2023년 1월 29일
0

C/C++

목록 보기
6/9

알고리즘 문제를 C/C++로 풀 때, 입출력 함수를 과연 C stdio vs C++ iostream 둘 중에 뭘로 쓸 것인가?

실험의 발단은 이렇다.

"평소에 stdio를 즐겨 쓰던 필자는 과연 속도의 이점을 위해 iostream으로 갈아타야 하는가??"

라는 궁금증이 생겨 직접 테스트를 해보았다.

결론부터 말하면 속도 상에 유의미한 차이는 없는 것 같았다.


1. 실험 방법

실험 방법은 이렇다.

어떤 알고리즘을 짜고, 입출력 함수만 다르게 하여 수행 시간을 비교하는 방식으로 진행하였다.

실험 조건

  • Windows 10 x64
  • Visual Studio 2019 (16.11.18)
  • Code
    • 백준 1992번 쿼드 트리 문제
    • 조건부 컴파일을 통해 stdio vs iostream 취사 선택 가능
  • Result
    • time.h의 clock() 함수를 이용하여 수행 시간 측정
    • n회 반복 측정하여 평균값 도출

본 실험에서는 100회 수행 후 평균값을 내는 방식으로 진행하였다.
그 이유는 코드를 실행할 때마다 측정되는 수행 시간이 달랐기 때문이다.

2. 코드 구현

필자가 구현한 코드는 아래와 같다.
C99/C++20 정답 코드를 기반으로 반복 수행 및 시간 측정 코드를 추가하였다.

그리고 조건부 컴파일을 이용해 stdio와 iostream을 취사 선택할 수 있도록 구성하였다.

  • main.c / main.cpp
#define _CRT_SECURE_NO_WARNINGS

#define __USE_IOSTREAM__ 0 // 1: iostream, 0: stdio
#define TEST_COUNT 100

#if __USE_IOSTREAM__ == 1
#include <iostream>
using namespace std;
#else
#include <cstdio>
#endif

int arr[65][65];
int N;

#include <ctime>

time_t time_start, time_end;

bool check(int y, int x, int len, int value)
{
	for (int i = y; i < y + len; i++)
	{
		for (int j = x; j < x + len; j++)
		{
			if (arr[i][j] != value)
				goto EXIT;
		}
	}

	return true;

EXIT:
	return false;
}

void quadtree(int y, int x, int len)
{
	if (len == 0) return;

	bool allzero = check(y, x, len, 0);
	bool allone  = check(y, x, len, 1);

	if (allzero)
	{
#if __USE_IOSTREAM__ == 1
		cout << "0";
#else
		printf("0");
#endif
		return;
	}

	if (allone)
	{
#if __USE_IOSTREAM__ == 1
		cout << "1";
#else
		printf("1");
#endif
		return;
	}

#if __USE_IOSTREAM__ == 1
	cout << "(";
#else
	printf("(");
#endif

	int half = len >> 1;

	quadtree(y, x, half);
	quadtree(y, x + half, half);
	quadtree(y + half, x, half);
	quadtree(y + half, x + half, half);

#if __USE_IOSTREAM__ == 1
	cout << ")";
#else
	printf(")");
#endif
}

int main(void)
{
	freopen("Text.txt", "r", stdin);

	int time_average = 0;

	for (int t = 0; t < TEST_COUNT; t++)
	{
#if __USE_IOSTREAM__ == 1
		ios::sync_with_stdio(false);
		cin.tie(0);
#endif

		time_start = clock();

#if __USE_IOSTREAM__ == 1
		cin >> N;
#else
		scanf("%d", &N);
#endif
		for (int i = 0; i < N; i++)
		{
			char temp[65];
#if __USE_IOSTREAM__ == 1
			cin >> temp;
#else
			scanf("%s", &temp);
#endif
			for (int j = 0; j < N; j++)
			{
				arr[i][j] = temp[j] - '0';
			}
		}

		quadtree(0, 0, N);

		time_end = clock();

		time_average += time_end - time_start;
	}

	time_average /= TEST_COUNT;

#if __USE_IOSTREAM__ == 1
	cout << "execution time: " << time_average;
#else
	printf("execution time: %d", time_average);
#endif

	return 0;
}

__USE_IOSTREAM__ 값을 1로 설정하면 iostream, 0으로 설정하면 stdio를 사용하도록 하였다.

그리고 iostream의 경우 아래 코드를 추가하여 버퍼 동기화를 비활성화하였다.

ios::sync_with_stdio(false);
cin.tie(0);

3. TC 작성

실험에 사용한 TC는 아래와 같다.
위 문제에서 입력으로 줄 수 있는 worst case를 작성하였다.

  • Text.txt
64
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101
1010101010101010101010101010101010101010101010101010101010101010
0101010101010101010101010101010101010101010101010101010101010101

3. 실험 결과

코드를 실행하고 약 30초 정도 기다리면 결과가 출력된다.

1. C stdio = 287

stdio를 사용했을 때 출력된 결과는 아래와 같았다.

execution time: 287

2. C++ iostream = 293

iostream를 사용했을 때 출력된 결과는 아래와 같았다.

execution time: 293

3. C++ iostream with buffer sync = 295

추가로 아래의 버퍼 동기화 비활성화 코드를 제거하고도 수행 시간을 측정해보았다. 결과는 아래와 같았다.

ios::sync_with_stdio(false);
cin.tie(0);

execution time: 295

4. 결론

속도 상에 유불리가 있을 것을 기대하였으나 측정값을 봤을 땐 그렇지 않은 것 같았다. 그리고 몇 번 더 실행해보면 서로 결과값이 역전되기도 하였다.

적어도 필자가 궁금했던 "입출력 함수를 갈아타야 하는가" 에 대한 결론은 "아니오" 로 난 것 같다.

profile
개발자입니당 *^^* 깃허브 https://github.com/pikamonvvs

0개의 댓글