2011-09-22 56 views
10

Gần đây tôi đã xem một tệp cấu hình đã lưu một số giá trị khó hiểu. Tôi tình cờ có nguồn sẵn có, vì vậy tôi đã xem xét những gì nó đang làm, và nó đã tiết kiệm được một loạt các giá trị khác nhau và bit chuyển chúng vào nhau. Nó làm tôi băn khoăn tại sao một người nào đó làm điều đó. Câu hỏi của tôi, sau đó, là: có một lợi thế rõ ràng để lưu trữ dữ liệu số theo cách này không? Tôi có thể thấy cách nó có thể làm cho một giá trị nhỏ hơn một chút để lưu trữ, byte-khôn ngoan, nhưng nó có vẻ như rất nhiều công việc để tiết kiệm một vài byte lưu trữ. Nó cũng có vẻ như nó sẽ chậm hơn đáng kể.Tại sao bit chuyển dịch?

Các khả năng khác xảy ra với tôi là được sử dụng cho mục đích làm xáo trộn. đây có phải là cách sử dụng phổ biến của dịch chuyển bit không?

+2

obfuscation bằng cách dịch chuyển bit có thể là một trong những phương tiện kém hiệu quả nhất từng có – KevinDTimm

+0

@KevinDTimm Tôi đã từng thấy tệp cấu hình được tạo bằng cách đặt mọi ký tự khác vào bộ đệm riêng biệt và sau đó kết hợp cả hai. Vì vậy, tệp 'configParam = true' được chuyển thành' cnfgaa reofiPrm = tr'. Bây giờ cho một param duy nhất, nó có thể trông đầy đủ, đủ để không tìm ra ngay lập tức. Đối với một tập tin toàn bộ được như vậy, mô hình là khá rõ ràng. Chỉ có điều, nó không chỉ là một tập tin cấu hình, nó là một tập tin giấy phép ... Mmmhmm ... Tôi đoán chỉ cần có nó được văn bản đơn giản và thực thi một chữ ký băm là quá phức tạp cho họ ... – corsiKa

Trả lời

5

Bit chuyển dường như phổ biến hơn trong các ngôn ngữ hệ thống cấp như C, C++ và lắp ráp, nhưng tôi đã nhìn thấy nó ở đâu đó trong C# quá. Nó không thường được sử dụng quá nhiều để tiết kiệm không gian, mặc dù, vì nó là cho một (hoặc cả hai) của hai lý do điển hình:

  • Bạn đang nói chuyện với một hệ thống hiện có (hoặc sử dụng một giao thức thành lập, hoặc tạo ra một tệp theo định dạng đã biết) yêu cầu nội dung phải được đặt chính xác; và/hoặc
  • Sự kết hợp các bit bao gồm một giá trị hữu ích cho việc thử nghiệm.

Bất cứ ai sử dụng nó trong một ngôn ngữ cấp cao chỉ để tiết kiệm không gian hoặc xáo trộn mã của họ là hầu như luôn luôn sớm tối ưu hóa (và/hoặc là một thằng ngốc). Tiết kiệm không gian hiếm khi biện minh cho sự phức tạp thêm vào, và sự dịch chuyển bit thực sự không đủ phức tạp để ngăn ai đó quyết định hiểu mã của bạn.

+0

Dường như với tôi đây là câu trả lời: có vẻ như không phải là một sự biện minh cho sự phức tạp thêm vào trong tập tin cấu hình. Nó là tốt để nghe về việc sử dụng thực tế của bit chuyển mặc dù. –

+0

Bạn có thể cần nó để lưu trữ ví dụ hai 'short' trong một trường 'int'eger trong trạng thái Session trong ASP.net mà không cần phải đọc và khóa Session để đọc hai giá trị riêng biệt. Ngoài ra, chi phí lưu trữ hai giá trị trong phiên được lưu. –

+2

@David: Và đó ... là một ví dụ chính về nơi nó * không nên * được sử dụng. Ít nhất là bạn đã lược tả và thấy rằng ứng dụng của bạn quá chậm hoàn toàn vì bạn đang đọc hai thông số phiên thay vì một. (PROTIP: trừ khi bạn là Microsoft, rất có khả năng *** không phải là vụ án. Xa, * xa * nhiều khả năng là thuật toán của bạn hút.) – cHao

11

Đây là một trong những cách sử dụng phổ biến của dịch chuyển bit. Có một số lợi ích:

1) Hoạt động dịch chuyển bit nhanh.

2) Bạn có thể lưu trữ nhiều cờ trong một giá trị duy nhất.

Nếu bạn có một ứng dụng mà có một số tính năng, nhưng bạn chỉ muốn nhất định (cấu hình) những người được kích hoạt, bạn có thể làm một cái gì đó như:

[Flags] 
public enum Features 
{ 
    Profile = 1, 
    Messaging = 1 << 1, 
    Signing = 1 << 2, 
    Advanced = 1 << 3 
} 

Và giá trị duy nhất của bạn để kích hoạt tính năng nhắn tin và nâng cao sẽ là:

(1 << 1) + (1 << 3) = 2 + 16 = 18 

<add name="EnabledFeatures" value="18" /> 

Và sau đó tìm hiểu xem liệu một đặc trưng nhất định được kích hoạt, bạn chỉ cần thực hiện một số toán bitwise đơn giản:

var AdvancedEnabled = 
    EnabledFeatures & Features.Advanced == Features.Advanced; 
+1

Tôi không thể hãy tưởng tượng nó nhanh hơn đáng kể khi thu thập một số ít giá trị từ một tệp mặc dù ... và tiết kiệm không gian trong loại ứng dụng này dường như không đáng kể. Có lẽ các nhà phát triển chỉ cần đi với một cái gì đó s/ông đã quen thuộc với. –

+0

Bạn cũng có thể thực hiện logic và/hoặc/Xor lạ trên giá trị (thường là biến trạng thái) để tìm ra trạng thái "hợp nhất". Thực sự kinh khủng, nhưng tôi thấy nó trong các ứng dụng 3D, trong việc kết xuất hạt nhân, mà chỉ thực sự là giải pháp để giữ với sự phức tạp của logic và không trả tiền trong hiệu suất. – Tigran

+1

Sự khác biệt này đáng kể so với việc có một enum với 1,2,4,8,16 vv giá trị? Điều này đạt được điều gì? –

4

Tôi có một dự án lưu trữ ma trận ngày/giờ của các giờ có sẵn trong một tuần. Vì vậy, nó có giá trị 24x7 mà phải được lưu trữ bằng cách nào đó.

Tôi đã chọn lưu trữ dưới dạng 7 int, vì vậy mỗi ngày được biểu thị bằng một số nguyên và mỗi giờ trong số đó là một bit. Chỉ là một ví dụ mà nó có thể hữu ích.

enter image description here

+0

Bổ sung lợi ích: 'if (available_hours [0]! = 0)' cho biết bạn có sẵn sàng vào Chủ Nhật (hay Thứ Hai, nếu bạn tham gia vào đó). – cHao

+0

Vâng, chính xác ... Cũng với thao tác AND hoặc OR đơn giản, các chồng chéo khác nhau có thể được tính ngay lập tức. –

+0

Hữu ích và mang tính thông tin. Tôi có thể thấy nhiều nơi tôi có thể sử dụng. Tuy nhiên, cách nó được sử dụng (trong một tập tin cấu hình) có vẻ không hợp lý. –

1

Đôi khi (đặc biệt là trong chương trình Windows cũ), sẽ có thông tin được mã hóa trong các bit "thứ tự cao" và "thứ tự thấp" của một giá trị ... và đôi khi cần phải thay đổi để lấy thông tin.Tôi không chắc chắn 100% lý do đằng sau điều đó, ngoài việc có thể trả về một giá trị 64 bit với hai giá trị 32 bit được mã hóa trong đó (để bạn có thể xử lý nó với một giá trị trả về đơn từ một phương thức) gọi điện).

Tôi đồng ý với các xác nhận của bạn về sự phức tạp không cần thiết, tôi không thấy nhiều ứng dụng bên ngoài công cụ khủng hoảng số/thực sự nặng nề ở đây sẽ là cần thiết.

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