2011-09-10 43 views
7

Tôi đang tạo một trò chơi mà tôi lưu trữ nhiều dữ liệu trong một số nguyên hoặc dài, bởi vì tôi sẽ có một lượng lớn dữ liệu. Tôi không muốn sử dụng toàn bộ các lớp vì lý do hiệu suất, và chúng không cần thiết. Tôi tìm thấy hai phương pháp để lấy một bit từ một số nguyên. Tôi đã tự hỏi nếu có ai biết tôi nên sử dụng cái nào hay cái nào nhanh hơn.Thuật toán nào nhanh hơn để kiểm tra xem một bit đã được đặt chưa?

Các phương pháp:

return (integer & (1 << bit)) != 0;

return (integer >> bit& 0x1) == 1;

+23

tối ưu hóa sớm là trò chơi ma quỷ – austinbv

+4

Chuẩn vi mô hoàn hảo để bạn thử. Chạy cả hai vòng lặp 1 triệu và thời gian. – Oded

+0

Tôi gần như hoàn toàn chắc chắn điều thứ hai chỉ đơn giản là _wrong_, bất kể nó có nhanh hơn hay không ... – bdonlan

Trả lời

16

Cơ hội là bit bạn đang thử nghiệm "không đổi" so với int bạn đang thử nghiệm. Do đó, bạn có thể tạo các hằng số cho bit, có nghĩa là bạn chỉ phải thực hiện ca làm việc một lần. Ví dụ:

static final int LEFT_WALL = 1 << 1; 
static final int RIGHT_WALL = 1 << 2; 
static final int BOTTOM_WALL = 1 << 3; 
static final int TOP_WALL = 1 << 4; 

Sau đó, trong vòng lặp của bạn, bạn chỉ cần kiểm tra

if ((integer & LEFT_WALL) != 0) 
    // left wall collision 
if ((integer & RIGHT_WALL) != 0) 
    // right wall collision 
... 

Vì vậy, bạn chỉ làm hai cuộc phẫu thuật (bitwise AND và so sánh) trong vòng lặp, không phải ba (shift, VÀ và so sánh).

Và quan trọng hơn (như được chỉ ra trong các nhận xét) so với tốc độ tăng, nó cũng làm cho nó rõ ràng hơn những gì bạn đang sử dụng mỗi bit, vì vậy mã dễ đọc hơn.

+6

Thậm chí tốt hơn so với tiết kiệm một op, tôi có thể đọc và làm cho tinh thần của nó một cách dễ dàng. – tvanfosson

+0

ý tưởng awsome. i tình cờ có gần như cùng một vars cuối cùng trong chương trình của tôi quá XD. btw hầu hết mọi người đang nói rằng đây không phải là một optomization rất quan trọng nhưng tại thời điểm nhất định tôi sẽ phải chạy này khoảng 24 triệu lần lol –

+1

@stas Yeah và bạn đang tiết kiệm một sự thay đổi theo cách đó, có lẽ với opop fusion và co chi phí có lẽ một nửa của một chu kỳ. Vì vậy, chạy 24 * 10^6 lần này giúp bạn tiết kiệm khoảng 12 triệu chu kỳ hoặc khoảng 4ms trên CPU 3ghz. Tiết kiệm tuyệt vời đó. – Voo

5

Đây là thực hiện phụ thuộc và phụ thuộc vào phần cứng và trình biên dịch của bạn. Không thực sự chạy bất kỳ thử nghiệm thời gian nào, tôi không nghĩ ai có thể nói điều đó sẽ tốt hơn.

Hơn nữa, tôi sẽ không lo lắng về một cái gì đó như thế này, trừ khi bạn có bằng chứng rõ ràng rằng mã này là rất thời gian quan trọng mà bạn phải tối ưu hóa nó. Chi tiêu thời gian vi mã hóa như thế này không có khả năng hiệu quả trừ khi bạn biết đó là một nút cổ chai hiệu suất, và tôi sẽ vô cùng ngạc nhiên nếu bạn không thể có được hiệu suất tiền thưởng nhiều hơn bằng cách tối ưu hóa các phần khác của mã. Hãy thử lược tả mã để xem những nút cổ chai thực sự là gì, sau đó đi tối ưu hóa những phần đó.

3

Chắc chắn không có sự khác biệt.

Nhưng cách duy nhất để chắc chắn, đối với nền tảng của bạn, là lập hồ sơ cho cả hai. Bạn sẽ cần phải đo thời gian cho một số lớn trong một vòng lặp mặc dù (như 100e6), để giảm thiểu lỗi đo lường.

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