สร้างโปรแกรม C ที่ใช้ระยะเวลายาวนานที่สุดในการคอมไพล์เป็น gcc


27

สร้างโปรแกรม C แบบสั้นที่ใช้เวลานานในการรวบรวม gcc รายการจะถูกทำคะแนนโดยกำหนดเวลาการรวบรวมจากนั้นลบเวลารวบรวมของโปรแกรมอ้างอิง

กฎระเบียบ

  • คุณลักษณะภาษา C หรือส่วนขยาย gcc ใด ๆ
  • gcc 4.2.1

1
เปลี่ยนการติดแท็กเพราะ [code-golf] หมายถึงอย่างชัดเจนว่า "shorted code by (key) count stroke"
dmckee

6
การหารด้วยจำนวนตัวละครไม่ค่อยสมเหตุสมผลนักเพราะวิธีการที่สมเหตุสมผลในการท้าทายนี้จะมีการรวบรวมเวลา - ความซับซ้อนที่มากขึ้นO ( n ) คือคะแนนของวิธีการแก้ปัญหาใด ๆ สามารถเพิ่มขึ้นได้เพียงแค่ทำให้มันเล็กน้อย อีกเล็กน้อยซึ่งอาจเป็นไปได้เสมอในทางที่ชัดเจน
หยุดที่จะหมุน counterclock ซึ่งเป็น

คำตอบ:


13
#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;

ไม่คอมไพล์บนเครื่องของฉัน
FUZxxl

19
อย่างน้อยที่สุดบรรทัดสุดท้ายจะต้องเปลี่ยนเป็นสิ่งที่ต้องการmain(){char*z=j;}ทำให้โปรแกรมนี้เป็น c ที่ถูกต้อง
dmckee

2
VS2012 ของฉันออกไปจากพื้นที่กอง ผมคิดว่า/Zmจะแก้ไขได้
รอบ

13

ทั้งคำตอบของ Charlieและคนก่อนหน้าของฉันทำงานบนหลักการของการให้ pre-processor เขียนโค้ดจำนวนมากแต่พวกเขาส่วนใหญ่ใช้ pre-processor ตัวเอง lexer (ความคิดที่ดีเนื่องจากขั้นตอนนี้ช้าแบบดั้งเดิม) และ parser ฉันก็พยายามที่จะเพิ่มประสิทธิภาพและขั้นตอนการสร้างรหัส แต่ก็เห็นได้ชัดว่าไม่ได้รับมาก

เมื่อคิดถึงว่าคอมไพเลอร์ทั่วไปทำงานอย่างไรฉันก็ตระหนักว่าเราไม่ได้ให้โค้ดเกี่ยวกับตารางสัญลักษณ์ที่เกี่ยวข้องกับสิ่งที่ต้องทำ รายการนี้เป็นความพยายามที่จะแก้ไข มันควรจะเตือนให้รำลึกถึงการวางแนวของวัตถุพื้นฐานในการใช้งาน c แต่ไม่ได้ทำอะไรที่น่าสนใจ: justuses เทคนิคการขยายตัวประมวลผลล่วงหน้าเพื่อประกาศและ trivially (และไม่ถูกต้อง) เริ่มต้นกลุ่มของวัตถุ วัตถุที่ใช้ชนิดที่ซับซ้อนบนขอบเขตหลายระดับทำให้เงาซึ่งกันและกันในการลบที่แตกต่างกัน มันควรจะให้ตารางสัญลักษณ์เป็นผลงานที่แท้จริง

#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)
}

เวลารวบรวมในเครื่องของฉันเกินกว่า 4 วินาที-O3และมากกว่า 1 วินาทีโดยไม่มีการปรับให้เหมาะสม


เห็นได้ชัดว่าขั้นตอนต่อไปคือการดำเนินการ OO ให้เสร็จสำหรับคลาส BCD และทำการคำนวณ pi อีกครั้งโดยใช้เพื่อให้ฉันได้รับผลกระทบทั้งสองอย่างเต็มที่


12

นี่คือ riff ของชุดรูปแบบ exponential-preprocessor-expansion ซึ่งทำสิ่งที่น่าสนใจน้อยที่สุด: คำนวณสองการประมาณเพื่อ pi ตามวิธีอนุกรมและเปรียบเทียบกับทั้งค่าในmath.hและคาถาปกติ

Ungolfed

#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และอาจหรืออาจจะไม่ทำงานกับข้อตกลงอื่น ๆ ใช้เวลาประมวลผลประมาณ 1.0-1.1 วินาที (ประเมินด้วยtime (1)) เพื่อคอมไพล์ด้วย-031ใน MacBook 2.4 GHz Intel Core 2 Duo ของฉัน การคอมไพล์เริ่มต้นใช้เวลาประมวลผลประมาณ 0.4 วินาที

อนิจจาฉันไม่สามารถรับ gcc เพื่อประเมินอย่างใดอย่างหนึ่งpowหรือtgammaตามเวลาคอมไพเลอร์ซึ่งจะช่วยได้จริงๆ

เมื่อคุณเรียกใช้ผลลัพธ์คือ:

pi (math.h) = 3.14159265
pi (trad.)  = 3.14159265
pi (NAIVE)  = 3.11503599
pi (EULER)  = 3.14159065

ซึ่งแสดงให้เห็นว่าซีรีส์ไร้เดียงสาช้าแค่ไหน


1เพื่อให้ได้การพับและการกำจัดนิพจน์ที่คงที่มากที่สุดเท่าที่จะทำได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.