2009-04-22 38 views
6

Lập trình meta mẫu có thể được sử dụng để tính toán những thứ như giai thừa trong thời gian biên dịch thay vì trong thời gian chạy. Tôi đã nghe nói rằng một số cuộc thi lập trình đã giới thiệu những hạn chế về thời gian biên dịch chính xác để loại bỏ sự lạm dụng lập trình meta mẫu.Biên soạn mẫu có thể mất bao lâu?

Có bất kỳ ví dụ tìm kiếm vô tội nào về việc sử dụng các mẫu có thời gian thực sự dài (như vài giờ) để biên dịch không?

Trả lời

3

Tôi nghe nói rằng Olympic quốc tế về Tin học (một cuộc thi lập trình) lần đầu tiên giới thiệu thời gian biên dịch sau khi một thí sinh tạo ra một vector 7 chiều sử dụng kỹ thuật giống như this. Mã của anh ta phải được biên soạn lại qua đêm nó rất tệ. Tôi nghĩ điều này đã xảy ra vào cuối những năm 90.

5

Cơ chế mẫu hoàn tất Turing. Điều này có nghĩa rằng trong lý thuyết ít nhất, bất kỳ tính toán có thể được thực hiện có thể được thực hiện tại thời gian biên dịch theo cách này (Trong thực tế, bạn có thể chạy vào giới hạn cứng về chiều sâu mẫu vv khá nhanh chóng nhưng điều này là trình biên dịch phụ thuộc).

Có hay không bạn muốn thực hiện việc này là một câu hỏi riêng. Bạn có thể trivially phù hợp với tiêu chí của bạn "giờ để biên dịch" bằng cách sử dụng một thuật toán đắt tiền. Nhưng cũng có nhiều mã thực tế hơn như this one implementing an FFT; cho rằng một dữ liệu đủ lớn đặt ra và nó sẽ mất một thời gian ...

+0

mất khoảng 25 giây trên Core2 Duo 2,66 với N = 1000. Đó là ấn tượng nhưng không phải là rất dài. Và mã này chắc chắn không ngây thơ. – sharptooth

+0

N = 1000 không phải là rất lớn ở tất cả cho một FFT. Tôi nên rõ ràng, tôi có nghĩa là "thực tế hơn" không phải vì đây là cách bạn muốn tính toán FFT, nhưng bởi vì nó là một thuật toán cực kỳ hữu ích (và được sử dụng khắp nơi) thay vì thực hiện một cái gì đó chỉ để mất một thời gian dài (như và đánh giá chức năng Ackerman) – simon

3

Hãy thử điều này (i sử dụng Visual Studio 2005)

template <int M, int N> 
struct Ack 
{ 
    enum { value = Ack<M - 1, Ack<M, N - 1>::value >::value }; 
}; 

template <int M> 
struct Ack<M, 0> 
{ 
    enum { value = Ack<M - 1, 0>::value }; 
}; 

template <> 
struct Ack<0, 0> 
{ 
    enum { value = 1 }; 
}; 

template <int N> 
struct Ack<0, N> 
{ 
    enum { value = N + 1 }; 
}; 

void main() 
{ 
    printf("Result: %d\n", Ack<150, 150>::value); 
} 

Nó có lẽ dường như horribble, tôi chỉ cố gắng để viết một tương đương này dễ thương chức năng lisp

(defun ack(m, n) 
cond ((= m 0) (+ n 1)) 
    ((= n 0) ack(- m 1) n) 
    (t (ack (- m 1) (ack m (-n 1)))) 
) 

giáo viên của chúng tôi nói nó là Ferma chức năng, nhưng tôi không chắc chắn ...

+2

http://en.wikipedia.org/wiki/Ackermann_function –

+2

Đã thử điều này với <116, 116> trên VC7 trên Core2 Duo 2,66 - mất khoảng 20 giây ấn tượng nhưng không phải là rất dài . Các giá trị lớn hơn gây ra lỗi biên dịch. – sharptooth

+0

Nếu nó là một chức năng ackermann, hãy thử nó với <5,5> sẽ làm cho máy tính của bạn phát nổ trước khi nhận được kết quả chính xác! Nếu bạn quản lý để có được <116,116> thì có gì đó không ổn. – CygnusX1

Các vấn đề liên quan