gcc로 컴파일하는 데 시간이 오래 걸리는 짧은 C 프로그램을 작성하십시오. 컴파일 시간을 정한 후 참조 프로그램의 컴파일 시간을 빼서 항목에 점수를 매 깁니다.
규칙
- 모든 C 언어 기능 또는 gcc 확장
- gcc 4.2.1
gcc로 컴파일하는 데 시간이 오래 걸리는 짧은 C 프로그램을 작성하십시오. 컴파일 시간을 정한 후 참조 프로그램의 컴파일 시간을 빼서 항목에 점수를 매 깁니다.
규칙
답변:
#define a "xxxxxxxxxxx"
#define b a a a a a a a
#define c b b b b b b b
#define d c c c c c c c
#define e d d d d d d d
#define f e e e e e e e
#define g f f f f f f f
#define h g g g g g g g
#define i h h h h h h h
#define j i i i i i i i
z=j;
main(){char*z=j;}
은 이것을 유효한 c 프로그램으로 만들기 위해 변경되어야 합니다.
/Zm
그것을 고칠 것 같아요
Charlie의 대답 과 이전 의 두 가지 모두 전처리 기가 많은 코드를 작성하도록하는 원칙에 대해 연구하고 있지만 대부분 전 처리기 자체, lexer (이 단계는 느리기 때문에 좋은 아이디어) 및 파서를 사용합니다. 광산은 또한 최적화 및 코드 생성 단계를 수행하려고 시도하지만 분명히 많이 얻지 못했습니다.
전형적인 c 컴파일러가 어떻게 작동하는지 생각하면서, 나는 우리가 수행 할 심볼 테이블 관련 코드를 제공하지 않았다는 것을 깨달았다. 이 항목은이를 해결하려는 시도입니다. c 구현에서 기본 객체 지향을 생각 나게하지만 흥미로운 것은 없습니다 : 전 프로세서 확장 기술을 사용하여 많은 객체를 선언하고 사소하게 (그리고 잘못) 초기화합니다. 다양한 범위의 범위에서 복잡한 유형을 사용하여 다양한 제거에서 서로를 음영 처리하는 객체입니다. 그것은 기호 테이블에 실제 운동을 제공해야합니다.
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
// Exercise the symbol table mechanism of the compiler in an effort to
// take a unreasonable about of time compiling
#define PTR(T) T*
#define CONST(T) T const
#define FUNC(NAME,RTYPE,ARG) RTYPE NAME(ARG)
#define FPTR(NAME,RTYPE,ARG) FUNC((*NAME),RTYPE,ARG)
// Forward decalration of repeated OO method pointers
typedef void* (*cctor_ptr)(void*this, void*that, ...);
typedef void* (*dtor_ptr)(void*this);
// Assumes three var-args: sizeof(payload type), cctor, dtor
void* default_ctor(void*this, ...){
// Pull in variadac bits
va_list list;
va_start(list,this);
int size=va_arg(list,int);
cctor_ptr cctor=va_arg(list,cctor_ptr);
dtor_ptr dtor=va_arg(list,dtor_ptr);
va_end(list);
// process
if (!this) this = malloc(size);
if (this) {
memset(this,size,0);
/* various dodges to install the cctor and dtor in the write places */
}
return this;
}
// Copies the payload from that to this;
void* default_cctor(void*restrict this, void* restrict that, ...){
// Pull in variadac bits
va_list list;
va_start(list,that);
int size=va_arg(list,int);
cctor_ptr cctor=va_arg(list,cctor_ptr);
dtor_ptr dtor=va_arg(list,dtor_ptr);
va_end(list);
// process
if (!this) this = malloc(size);
if (this) {
memcpy(this,that,size);
/* various dodges to install the cctor and dtor in the write places */
}
return this;
}
// Assumes that his was allocated with malloc, does not use varargs
void* default_dtor(void*this, ...){
free(this);
return NULL;
};
#define DECLARE_STRUCT(N) struct S##N##_s
#define TYPEDEF_ACCESSOR(N,T) typedef FPTR(f##N##_ptr,CONST(PTR(T)),PTR(CONST(struct S##N##_s)))
#define TYPEDEF_STRUCT(N,T) typedef struct S##N##_s {PTR(T)p; cctor_ptr cctor; dtor_ptr dtor; f##N##_ptr f##N;} S##N
#define OO_STRUCT(N,T) DECLARE_STRUCT(N); TYPEDEF_ACCESSOR(N,T); TYPEDEF_STRUCT(N,T)
OO_STRUCT(1,char);
OO_STRUCT(2,int);
OO_STRUCT(3,double*);
OO_STRUCT(4,S3);
OO_STRUCT(5,S4);
OO_STRUCT(6,S5);
OO_STRUCT(7,S6);
OO_STRUCT(8,S7);
#define SUBSCOPE(A) { \
S1*A##1=default_ctor(NULL,sizeof(char),default_cctor,default_dtor); \
S2 A##2; default_ctor(&A##2,sizeof(int),default_cctor,default_dtor); \
S2*A##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S8 A##5; default_ctor(&A##5,sizeof(S4),default_cctor,default_dtor); \
S6 A##6; default_ctor(&A##6,sizeof(S5),default_cctor,default_dtor); \
S8*A##8=default_ctor(NULL,sizeof(S7),default_cctor,default_dtor); \
}
#define SUBSCOPE2(A,B) { \
S2*B##5=default_ctor(NULL,sizeof(S4),default_cctor,default_dtor); \
S4 A##7; default_ctor(&A##7,sizeof(S6),default_cctor,default_dtor); \
SUBSCOPE(A) SUBSCOPE(B); \
}
#define SUBSCOPE6(A,B,C) { \
S2*A##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S2 B##2; default_ctor(&B##2,sizeof(int),default_cctor,default_dtor); \
S4*C##4=NULL; \
SUBSCOPE2(A,C) SUBSCOPE2(B,C) SUBSCOPE2(A,B); \
}
#define SUBSCOPE24(A,B,C,D) { \
S1*D##1=default_ctor(NULL,sizeof(char),default_cctor,default_dtor); \
S2 C##2; default_ctor(&C##2,sizeof(int),default_cctor,default_dtor); \
S2*B##3=default_ctor(NULL,sizeof(double*),default_cctor,default_dtor); \
S4 A##4; default_ctor(&A##4,sizeof(S3),default_cctor,default_dtor); \
SUBSCOPE6(A,B,C) SUBSCOPE6(A,B,D) SUBSCOPE6(A,C,D) SUBSCOPE6(B,C,D); \
}
#define SUBSCOPE120(A,B,C,D,E) { \
S5*A##5=default_ctor(NULL,sizeof(S4),default_cctor,default_dtor); \
S6*A##6=default_ctor(NULL,sizeof(S5),default_cctor,default_dtor); \
S8 A##8; default_ctor(&A##8,sizeof(S7),default_cctor,default_dtor); \
SUBSCOPE24(A,B,C,D) SUBSCOPE24(A,B,C,E) SUBSCOPE24(A,B,D,E); \
SUBSCOPE24(A,C,D,E) SUBSCOPE24(B,C,D,E); \
}
#define SUBSCOPE720(A,B,C,D,E,F) { \
S5 A##5; default_ctor(&A##5,sizeof(S4),default_cctor,default_dtor); \
S6 A##6; default_ctor(&A##6,sizeof(S5),default_cctor,default_dtor); \
S8*A##8=default_ctor(NULL,sizeof(S7),default_cctor,default_dtor); \
SUBSCOPE120(A,B,C,D,E) SUBSCOPE120(A,B,C,D,F) SUBSCOPE120(A,B,C,E,F); \
SUBSCOPE120(A,B,D,E,F) SUBSCOPE120(A,C,D,E,F) SUBSCOPE120(B,C,D,E,F); \
}
int main(){
S4 s4;
SUBSCOPE720(A,B,C,D,E,F)
}
내 컴퓨터의 컴파일 시간이 -O3
최적화없이 4 초를 초과하고 1 초 이상입니다.
분명히 다음 단계는 BCD 클래스에 대한 OO 구현을 끝내고 그것을 사용하여 pi 계산을 다시 수행하여 두 가지 효과를 모두 실행하는 것입니다.
다음은 최소한의 흥미로운 것을 수행하는 지수 전 처리기 확장 테마의 리프입니다. 일련의 방법으로 pi에 대한 두 개의 근사값을 계산하고 math.h
하고 일반적인 incantation .
언 골프.
#include <math.h>
#include <stdio.h>
// Some random bits we'll need
#define MINUSONODD(n) (n%2?-1:+1)
#define TWON(n) (2*(n))
#define NPLUSONE(n) ((n)+1)
#define TWONPLUSONE(n) NPLUSONE(TWON(n))
#define FACT(n) (tgamma(NPLUSONE(n)))
// The Euler series
// 2^(2n) * (n!)^2 z^(2n+1)
// atan(z) = \sum_n=0^\infty --------------- * ---------------
// (2n+1)! (1 + z^2)^(n+1)
#define TERMEULER(n,z) (pow(2,TWON(n))* \
FACT(n)*FACT(n)* \
pow((z),TWONPLUSONE(n))/ \
FACT(TWONPLUSONE(n)) / \
pow((1+z*z),NPLUSONE(n)) )
// The naive version
// (-1)^n * z^(2n+1)
// atan(z) = \sum_n=0^\infty -----------------
// 2n + 1
#define TERMNAIVE(n,z) (MINUSONODD(n)*pow(z,TWONPLUSONE(n))/TWONPLUSONE(n))
// Define a set of bifruncations of the sum
#define N2TERMS(n,z,ALG) (TERM##ALG(TWON(n),(z)) + TERM##ALG(TWONPLUSONE(n),(z)))
#define N4TERMS(n,z,ALG) (N2TERMS(TWON(n),(z),ALG)+N2TERMS(TWONPLUSONE(n),(z),ALG))
#define N8TERMS(n,z,ALG) (N4TERMS(TWON(n),(z),ALG)+N4TERMS(TWONPLUSONE(n),(z),ALG))
#define N16TERMS(n,z,ALG) (N8TERMS(TWON(n),(z),ALG)+N8TERMS(TWONPLUSONE(n),(z),ALG))
#define N32TERMS(n,z,ALG) (N16TERMS(TWON(n),(z),ALG)+N16TERMS(TWONPLUSONE(n),(z),ALG))
// Sum the fist 32*2+16 = 80 terms of a series...
#define PARTIALSUM(z,ALG) N32TERMS(0,(z),ALG)+N32TERMS(1,(z),ALG)+N16TERMS(4,(z),ALG)
int main(void){
const double PI_TRAD = 4.0L * atan(1.0);
const double PI_NAIVE = 4.0L * PARTIALSUM(0.999999L,NAIVE);
const double PI_EULER = 4.0L * PARTIALSUM(0.999999L,EULER);
printf("pi (math.h) = %10.8f\n",M_PI);
printf("pi (trad.) = %10.8f\n",PI_TRAD);
printf("pi (NAIVE) = %10.8f\n",PI_NAIVE);
printf("pi (EULER) = %10.8f\n",PI_EULER);
}
당신이 사용하고 있다고 가정 gcc
및 glibc
및 또는 다른 장치에서 작동하지 않을 수 있습니다. 1time (1)
로 컴파일하려면 약 1.0-1.1 초의 프로세서 시간 (로 평가됨 )이 필요합니다-03
2.4GHz Intel Core 2 Duo MacBook . 기본 컴파일은 약 0.4 초의 프로세서 시간이 걸립니다.
아아, 나는 gcc에게 pow
또는tgamma
컴파일러 시간 컴파일러 시간 실제로 도움이 될 것입니다.
실행할 때 출력은 다음과 같습니다.
pi (math.h) = 3.14159265
pi (trad.) = 3.14159265
pi (NAIVE) = 3.11503599
pi (EULER) = 3.14159065
순진한 시리즈가 얼마나 느리게 수렴되는지 보여줍니다.
1 가능한 한 일정한 접힘 및 하위 표현 제거를 얻기 위해.