2008-10-15 24 views
26

Tại sao một Boolean tiêu thụ 4 byte và một byte 2 byte trong khuôn khổ .NET? Một Boolean nên chiếm 1bit hoặc ít nhất là nhỏ hơn một char.Tại sao boolean tiêu thụ nhiều bộ nhớ hơn char?

+0

Tôi đã tự hỏi chính câu hỏi đó. – QuantumPete

+0

trong tò mò, bao nhiêu không gian làm 2 booleans trong một cấu trúc mất? – workmad3

+0

Bạn đang mong đợi bao nhiêu boolean? Bình thường valuetypes sẽ chỉ được tiêu thụ bởi các ngăn xếp, vì vậy trừ khi bạn đang đối phó với một số lượng lớn các bools (giống như một chuỗi ký tự), tôi sẽ không lo lắng. – leppie

Trả lời

50

Đây là câu hỏi liên kết bộ nhớ. Biến 4 byte hoạt động nhanh hơn các biến 2 byte. Đây là lý do tại sao bạn nên sử dụng int thay vì byte hoặc ngắn cho các quầy và tương tự.

Bạn chỉ nên sử dụng các biến 2 byte khi bộ nhớ là mối quan tâm lớn hơn tốc độ. Và đây là lý do tại sao char (đó là Unicode trong. NET) mất hai byte thay vì bốn.

+5

Bạn thường không thể tham khảo các bit của bộ nhớ bằng cách sử dụng các kiến ​​trúc tiêu chuẩn và làm như vậy sẽ rất không hiệu quả. Byte thường là đơn vị địa chỉ nhỏ nhất và trong trường hợp này, char được xem là 2 byte. – workmad3

+4

Các boolean không được hộp thư mất 1 byte - xem bên dưới; điều này đơn giản không phải là câu trả lời hợp lệ cho các câu hỏi. – Blaisorblade

1

Tôi thấy điều này: "Thực ra, Boolean là 4 byte, không phải 2. Lý do là CLR hỗ trợ cho Boolean. Tôi nghĩ đó là những gì nó làm bởi vì giá trị 32 bit hiệu quả hơn nhiều để thao tác, vì vậy sự cân bằng thời gian/không gian, nói chung, đáng giá. Bạn nên sử dụng lớp bit bit (quên nó ở đâu) nếu bạn cần mứt một đống bit với nhau ... "

Nó được viết bởi Paul Wick tại http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx

+0

Huh! .NET nên ngừng đưa ra quyết định cho chúng tôi. –

+2

@Vulcan Eager: Đó là một trò đùa phải không? Toàn bộ quan điểm của .NET là nó đưa ra rất nhiều quyết định cho chúng tôi (như thu gom rác thải ....) –

+1

Tôi đồng ý với Giovanni Galbo, nếu bạn muốn kiểm soát hoàn toàn, bạn nên làm các công cụ trong C hoặc ASM. Vẻ đẹp của .NET và C# là những vấn đề như thế này được chăm sóc bởi những người có lẽ thông minh hơn tôi nhiều. –

8

Đó là vì trong môi trường 32 bit, CPU có thể xử lý các giá trị 32 bit nhanh hơn giá trị 8 bit hoặc 16 bit, vì vậy đây là tốc độ cân bằng/tốc độ. Nếu bạn phải tiết kiệm bộ nhớ và bạn có số lượng lớn bool, chỉ cần sử dụng uint s và lưu các boolean của bạn dưới dạng các bit của 4 byte uint s. Ký tự có chiều rộng 2 byte vì chúng lưu trữ các ký tự Unicode 16 bit.

1

Bộ nhớ chỉ là mối quan ngại nếu bạn có một mảng lớn các bit, trong trường hợp đó bạn có thể sử dụng lớp System.Collections.BitArray.

1

Trước hết, bạn nên sử dụng trình lược tả để xác định nơi nào bạn gặp vấn đề về bộ nhớ, IMHO.

0

Vì Windows và .Net đã sử dụng Unicode(UTF 16) kể từ khi khởi đầu làm bộ ký tự bên trong của chúng. UTF 16 sử dụng 2 byte cho mỗi ký tự hoặc một cặp 2 byte mỗi ký tự nhưng chỉ khi được yêu cầu vì nó là variable width encoding.

"Đối với nhân vật trong Basic Multilingual Plane (BMP) mã hóa kết quả là một đơn 16-bit từ. Đối với các nhân vật trong những chiếc máy bay khác, mã hóa sẽ cho kết quả trong một cặp từ 16-bit"

Tôi đoán về booleans sẽ là họ là bốn byte như đăng ký mặc định là 32 bit và điều này sẽ là kích thước tối thiểu. Net có thể làm một hoạt động hợp lý trên hiệu quả, trừ khi sử dụng các hoạt động bitwise.

15

Về boolean

Hầu hết các câu trả lời khác nhận được nó sai - liên kết và tốc độ là lý do tại sao một lập trình viên nên dính vào int cho quầy vòng lặp, không lý do tại sao các trình biên dịch có thể làm cho một byte là 4-byte rộng. Tất cả các lý do của bạn, trên thực tế, áp dụng cho byte và ngắn cũng như boolean. Trong ít nhất, bool (hoặc System.Boolean) là cấu trúc nội trang rộng 1 byte, có thể được tự động đóng hộp, vì vậy bạn có một đối tượng (cần hai từ bộ nhớ được biểu diễn, ít nhất là ít nhất là , tức là 8/16 byte trên 32/64 bit môi trường tương ứng) với một trường (ít nhất một byte) cộng với một từ bộ nhớ để trỏ đến nó, tức là trong tổng số ít nhất 13/25 byte.

Đó thực sự là mục nhập đầu tiên của Google trên "loại nguyên thủy C#". http://msdn.microsoft.com/en-us/library/ms228360(VS.80).aspx

Ngoài ra liên kết được trích dẫn (http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx) cũng cho biết rằng boolean, theo tiêu chuẩn CLI, mất 1 byte.

Trên thực tế, tuy nhiên, nơi duy nhất hiển thị này là trên mảng các boolean - n booleans sẽ lấy n byte. Trong các trường hợp khác, một boolean có thể mất 4 byte.

  • Bên trong một cấu trúc, hầu hết thời gian chạy (cũng bằng Java) sẽ căn chỉnh tất cả các trường thành ranh giới 4 byte để thực hiện. Các JVM Monty cho các thiết bị nhúng là khôn ngoan hơn - tôi đoán nó sắp xếp lại các lĩnh vực tối ưu.
    • Trên khung cục bộ/toán hạng cho trình thông dịch, trong hầu hết việc triển khai, để thực hiện, một mục nhập ngăn xếp là một từ rộng bộ nhớ (và có thể trên .NET nó phải rộng 64 bit để hỗ trợ gấp đôi và dài , mà trên .NET chỉ sử dụng 1 mục nhập stack thay vì 2 trong Java). Một trình biên dịch JIT thay vào đó có thể sử dụng 1 byte cho người dân địa phương boolean trong khi vẫn giữ các vars khác liên kết bằng cách sắp xếp lại các trường không có tác động hiệu suất, nếu chi phí bổ sung đáng giá.

Về char

char hai byte vì khi hỗ trợ cho quốc tế hóa là cần thiết, sử dụng ký tự hai byte trong nội bộ là đặt cược an toàn nhất. Điều này không liên quan trực tiếp đến việc chọn hỗ trợ Unicode, nhưng với sự lựa chọn để gắn vào UTF-16 và với Máy bay đa ngôn ngữ cơ bản. Trong Java và C#, bạn có thể giả sử tất cả thời gian mà một logic hợp lý phù hợp với một biến kiểu char.

+0

Bạn * có thể * sử dụng các ký tự bên ngoài BMP trong C# và chúng được biểu diễn bằng cách sử dụng hai 'char'. Mặc dù nó khá hiếm. – svick

2

Bạn cũng nên sử dụng boolean để giúp viết mã có thể bảo trì. Nếu tôi liếc nhìn mã thấy rằng một cái gì đó là một boolean là nhiều hơn thì đáng giá trị tiết kiệm bộ nhớ để tìm ra rằng bạn sử dụng char như booleans.

3

Bất kể sự khác biệt nhỏ trong lưu trữ bộ nhớ, sử dụng Boolean cho giá trị đúng/sai có/không quan trọng đối với nhà phát triển (bao gồm cả chính bạn, khi bạn phải truy cập lại mã sau một năm), vì nó phản ánh chính xác hơn ý định của bạn . Làm cho mã của bạn dễ hiểu hơn là quan trọng hơn nhiều so với việc tiết kiệm hai byte.

Làm cho mã của bạn phản ánh chính xác hơn ý định của bạn cũng làm giảm khả năng tối ưu hóa một số trình biên dịch sẽ có tác động tiêu cực. Lời khuyên này vượt qua các nền tảng và trình biên dịch.

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