Sau khi đọc chủ đề này, tôi đã thực hiện một thí nghiệm nhỏ, mang lại hai phát hiện khác biệt và thú vị.
Hãy xem xét những điều sau đây.
strInstallString "1" string
Ở trên được sao chép từ cửa sổ cục bộ của trình gỡ lỗi Visual Studio. Cùng một giá trị được sử dụng trong cả ba ví dụ sau.
if (strInstallString == "") === if (strInstallString == string.Empty)
Tiếp theo là các mã được hiển thị trong cửa sổ tháo của Visual Studio 2013 debugger cho hai về cơ bản giống hệt nhau các trường hợp.
if (strInstallString == "")
003126FB mov edx,dword ptr ds:[31B2184h]
00312701 mov ecx,dword ptr [ebp-50h]
00312704 call 59DEC0B0 ; On return, EAX = 0x00000000.
00312709 mov dword ptr [ebp-9Ch],eax
0031270F cmp dword ptr [ebp-9Ch],0
00312716 sete al
00312719 movzx eax,al
0031271C mov dword ptr [ebp-64h],eax
0031271F cmp dword ptr [ebp-64h],0
00312723 jne 00312750
if (strInstallString == string.Empty)
00452443 mov edx,dword ptr ds:[3282184h]
00452449 mov ecx,dword ptr [ebp-50h]
0045244C call 59DEC0B0 ; On return, EAX = 0x00000000.
00452451 mov dword ptr [ebp-9Ch],eax
00452457 cmp dword ptr [ebp-9Ch],0
0045245E sete al
00452461 movzx eax,al
00452464 mov dword ptr [ebp-64h],eax
00452467 cmp dword ptr [ebp-64h],0
0045246B jne 00452498
if (strInstallString == string.Empty) là không đáng kể khác nhau
if (strInstallString.Length == 0)
003E284B mov ecx,dword ptr [ebp-50h]
003E284E cmp dword ptr [ecx],ecx
003E2850 call 5ACBC87E ; On return, EAX = 0x00000001.
003E2855 mov dword ptr [ebp-9Ch],eax
003E285B cmp dword ptr [ebp-9Ch],0
003E2862 setne al
003E2865 movzx eax,al
003E2868 mov dword ptr [ebp-64h],eax
003E286B cmp dword ptr [ebp-64h],0
003E286F jne 003E289C
Từ danh sách mã máy trên, được tạo ra bởi các mô-đun NGEN của .NET Framework, phiên bản 4.5 , Tôi rút ra các kết luận sau đây.
Kiểm tra tính bình đẳng đối với chuỗi ký tự trống và chuỗi tĩnh.Địa chỉ trống trên lớp System.string, cho tất cả mục đích thực tế, giống hệt nhau. Sự khác biệt duy nhất giữa hai đoạn mã là nguồn của lệnh di chuyển đầu tiên, và cả hai đều là các offset tương ứng với ds, ngụ ý rằng cả hai tham chiếu đến các hằng số được nạp sẵn.
Kiểm tra tính bình đẳng đối với chuỗi trống, dưới dạng thuộc tính theo chuỗi hoặc thuộc tính string.Empty, thiết lập cuộc gọi hàm hai đối số, cho biết bất bình đẳng bằng cách trả về số không. Tôi căn cứ vào kết luận này về các bài kiểm tra khác mà tôi đã thực hiện một vài tháng trước, trong đó tôi theo một số mã của riêng tôi trên phân chia quản lý/không được quản lý và ngược lại. Trong mọi trường hợp, bất kỳ cuộc gọi nào yêu cầu hai hoặc nhiều đối số đều đặt đối số đầu tiên trong ECX đăng ký và đối số thứ hai trong thanh ghi EDX. Tôi không nhớ các lập luận tiếp theo đã được thông qua như thế nào. Tuy nhiên, thiết lập cuộc gọi trông giống như __fastcall hơn __stdcall. Tương tự như vậy, giá trị trả về dự kiến luôn hiển thị trong EAX đăng ký, gần như là phổ biến.
Kiểm tra độ dài của chuỗi thiết lập cuộc gọi hàm một đối số, trả về 1 (trong EAX đăng ký), xảy ra là độ dài của chuỗi đang được kiểm tra.Cho rằng mã máy ngay lập tức có thể nhìn thấy gần như giống hệt nhau, lý do duy nhất tôi có thể hình dung rằng hiệu suất của chuỗi bình đẳng trên chiều dài sting được báo cáo bởi Shinny là hàm hai đối số thực hiện so sánh được tối ưu hóa tốt hơn đáng kể so với hàm một đối số đọc độ dài của thể hiện chuỗi.
Kết luận
Là một vấn đề nguyên tắc, tôi tránh so sánh với chuỗi rỗng như một chữ, vì chuỗi rỗng đen có thể xuất hiện mơ hồ trong mã nguồn. Để kết thúc, các lớp trợ giúp .NET của tôi từ lâu đã định nghĩa chuỗi rỗng làm hằng số. Mặc dù tôi sử dụng chuỗi.Empty để so sánh trực tiếp, nội tuyến kiếm được hằng số để xác định các hằng số khác có giá trị là chuỗi rỗng, vì hằng số không thể được gán string.Empty làm giá trị của nó.
Bài tập này giải quyết, một lần và cho tất cả mọi thắc mắc về chi phí, nếu có, so sánh với số chuỗi.Empty hoặc hằng số được xác định bởi lớp trợ giúp của tôi.
Tuy nhiên, nó cũng đặt ra một câu hỏi khó hiểu để thay thế nó; tại sao so sánh với string.Empty hiệu quả hơn kiểm tra độ dài của chuỗi? Hoặc là thử nghiệm được sử dụng bởi Shinny vô hiệu hóa bởi vì bằng cách vòng lặp được thực hiện? (Tôi thấy khó tin, nhưng, sau đó một lần nữa, tôi đã bị lừa trước đây, như tôi chắc chắn rằng bạn có, quá!)
Tôi đã giả định rằng hệ thống.string đối tượng được tính chuỗi, về cơ bản tương tự như chuỗi cơ bản được thiết lập lâu dài (BSTR) mà chúng ta đã biết từ lâu từ COM.
Tôi nghĩ rằng OP đã hỏi về xác nhận chuỗi trống, không phải là vô hiệu, vì vậy khi bạn đã biết rằng chuỗi không phải là null, việc sử dụng IsNullOrEmpty chỉ là một kiểm tra không cần thiết khác. Vì vậy, câu hỏi của OP là những gì có hiệu suất hơn, myString.Length> 0 hoặc myString! = "". Đọc http://stackoverflow.com/questions/10230/checking-for-string-contents-string-length-vs-empty-string/2306659#2306659 – Shimmy