2012-01-23 15 views
10

Hôm nay, tôi gặp một tình huống mà tôi cần quyết định nếu toàn bộ cấu trúc bao gồm khoảng 40 phần tử bằng không - nghĩa là mỗi phần tử bằng 0.
Khi nghĩ làm thế nào để làm cho nó càng nhanh và hiệu quả càng tốt, tôi nghĩ về 3 cách khác nhau để làm như vậy:Cách ưa thích để so sánh cấu trúc với số không

  1. so sánh từng phần tử bằng không, kết quả là 40 nếu phát biểu.
  2. phân bổ một cấu trúc tương tự được allready zeroed và memcmp nó với cấu trúc.
  3. gói cấu trúc trong một liên minh với một loại đủ lớn để trang trải tất cả.

ví dụ

typedef union { 
    struct { 
    uint8_t a; 
    uint8_t b; 
    } 
    uint16_t c; 
} STRUCTURE_A; 

và sau đó so sánh nó không.

Tôi muốn biết suy nghĩ của bạn về những giải pháp này, bạn sẽ tìm thấy giải pháp nào nhanh nhất và hiệu quả nhất.
Và nếu bạn có cách tiếp cận tốt hơn, hãy cho tôi biết ...
Cảm ơn bạn.

+0

Có gì sai khi chỉ cần kiểm tra toàn bộ cấu trúc trong câu lệnh 'if', giống như bạn có thể cho cờ không? –

+3

Đừng quên đệm! – NPE

+1

Bạn đã thực hiện từng cách trong ba cách khác nhau của mình và so sánh hiệu suất của chúng chưa? Bạn đã tìm thấy gì? –

Trả lời

15

Hãy so sánh mỗi thành viên của cấu trúc để 0.

Đây là cách duy nhất an toàn để so sánh hai cấu trúc vật thể (thậm chí nếu một trong số các đối tượng cấu trúc có tất cả các thành viên thiết lập với giá trị 0). Không sử dụng memcmp để so sánh cấu trúc, giá trị của byte của phần đệm trong cấu trúc không được chỉ định. Cũng lưu ý rằng nó không được phép sử dụng toán tử == với toán hạng đối tượng cấu trúc.

Xem liên kết này c-faq trên so sánh đối tượng cấu trúc:

Q: Is there a way to compare structures automatically?

+1

Nếu bạn đã đảm bảo rằng cấu trúc không chứa padding, 'memcmp' là an toàn. Trong khi thực hiện về mặt kỹ thuật được phép thêm đệm vô nghĩa tùy ý, trong đệm thế giới thực hoàn toàn là căn chỉnh, và cấu trúc được sắp xếp hợp lý, tự nhiên sẽ không có đệm ngoại trừ khả năng ở cuối. Đặc biệt, bằng cách sử dụng 'intX_t' và sắp xếp chúng mà không có khoảng trống liên kết là một cách tốt để tránh bất kỳ padding nào. –

+0

Nếu cấu trúc không chứa padding và 'memcmp' thực sự * là * nhanh hơn, trình tối ưu hóa chắc chắn sẽ thấy điều đó và chuyển đổi các so sánh của bạn cho phù hợp. –

+0

Hy vọng rằng ...... –

1

Nếu kích thước cấu trúc của bạn là < = kích thước chữ của bộ xử lý, bạn có thể làm công đoàn lừa, tuy nhiên, bất kỳ trình biên dịch tốt của bạn nên làm điều này tự động, aka nó sẽ nhỏ gọn của if 's, cho phép cho rõ ràng nhưng vẫn giữ hiệu suất lên đến đầu.

0

Để rõ ràng về mã và như những người khác đã chỉ ra, để tránh các sự cố gây ra bởi việc đệm, hãy kiểm tra từng thành viên là tốt nhất.

Để biết tốc độ, hãy bắt đầu với một cái gì đó như thế này mà chỉ cần kiểm tra từng byte để xem nếu nó là số không.

int iszero(void * ptr, int bytes) 
{ 
    char * bptr = (char*)ptr; 
    while(bytes--) 
    if(*bptr++) 
     return 0; 
    return 1; 
} 

Sau đó, tối ưu hóa để thực hiện so sánh từ. Hãy xem triển khai của newlib về những thứ như strlen() & memcpy() để biết các ví dụ về cách thực hiện.

+0

Điều này tương đương với 'memcmp' và có thể có vấn đề về đệm. –

+0

@R .. Không, nó không tương đương với memcmp() vì không có cấu trúc thừa không có liên quan ở đây. Việc truy cập bộ nhớ thêm trong memcmp() có thể tồi tệ hơn gấp đôi thời gian truy cập bộ nhớ bởi vì bạn làm hai lần đọc mỗi lần VÀ bạn có thể có bộ nhớ đệm bị trashing trên các cấu trúc lớn. Tôi đã không được coi là vấn đề padding. Nhưng nếu bạn biết không có padding (ví dụ như trong GCC sử dụng gói pragma), tôi sẽ đứng bởi lập luận của tôi rằng kỹ thuật này là nhanh nhất. –

+0

Bởi "tương đương" tôi có nghĩa là nó có cùng một hành vi (và vấn đề padding), nhưng tôi mời bạn so sánh hiệu suất. Mã của bạn (byte-by-byte) là rất chậm mà ngay cả với nhiều lần đọc, 'memcmp' sẽ giành chiến thắng. Một 'memcmp' tốt so sánh 4, 8 hoặc thậm chí 16 byte tại một thời điểm. BTW "đóng gói" không phải là cách để sửa chữa các vấn đề liên kết. Nhận xét của tôi về câu trả lời của ouah là cách chính xác. –