2009-10-21 16 views
32

Tôi biết việc đánh dấu các tham số chuỗi là const có thể tạo ra sự khác biệt về hiệu suất rất lớn, nhưng về loại thứ tự thì sao? Tôi có kiếm được gì không bằng cách đặt chúng const?Có lợi thế nào khi sử dụng các tham số const với một loại thứ tự không?

Tôi luôn sử dụng const thông số khi xử lý chuỗi, nhưng không bao giờ cho Integer, Pointer, trường lớp, vv

Khi sử dụng const tôi thường phải tạo ra các biến tạm thời bổ sung, thay thế bây giờ viết được bảo vệ bằng các thông số, vì vậy tôi tự hỏi: Tôi có thu được gì từ việc đánh dấu các thông số thứ tự là const không?

Trả lời

43

Bạn cần phải hiểu lý do, để tránh "lập trình vận chuyển hàng hóa". Việc đánh dấu chuỗi như const tạo ra sự khác biệt hiệu suất bởi vì bạn không còn cần phải sử dụng tăng xen kẽ và giảm số lần truy cập trên chuỗi, hoạt động thực sự trở nên đắt hơn, không ít hơn, khi thời gian trôi qua vì nhiều lõi hơn nghĩa là nhiều công việc hơn điều đó phải được thực hiện để giữ nguyên các hoạt động nguyên tử. Điều này là an toàn để làm vì trình biên dịch thực thi ràng buộc "biến này sẽ không bị thay đổi".

Đối với các phân số, thường là 4 byte trở xuống, sẽ không đạt được hiệu suất. Sử dụng const làm tối ưu hóa chỉ hoạt động khi bạn đang sử dụng các loại giá trị lớn hơn 4 byte, chẳng hạn như mảng hoặc bản ghi hoặc các loại được tính tham chiếu như chuỗi và giao diện.

Tuy nhiên, có một lợi thế quan trọng khác là: khả năng đọc mã. Nếu bạn chuyển một thứ gì đó như const và nó không tạo ra sự khác biệt nào cho trình biên dịch, nó vẫn có thể tạo sự khác biệt cho bạn, vì bạn có thể đọc mã và thấy rằng ý định của nó là không sửa đổi. Điều đó có thể đáng kể nếu bạn chưa từng nhìn thấy mã trước đó (ai đó đã viết nó) hoặc nếu bạn quay lại sau một thời gian dài và không nhớ chính xác bạn đang nghĩ gì khi bạn viết nó lần đầu.

+0

+1 chắc chắn là một lời giải thích thỏa mãn hơn là của riêng tôi – jpfollenius

+13

Đoạn đầu tiên của bạn là sai về chuỗi. Các chuỗi luôn được truyền dưới dạng biểu diễn con trỏ bốn byte của chúng. 'Const' ngăn chặn mã trong phần mở đầu của hàm và phần kết thúc để cập nhật số tham chiếu của chuỗi. Cũng vậy với các tham số giao diện và mảng động. Tương tự, các bản ghi được chuyển thành con trỏ. 'Const' chỉ đơn thuần là ngăn chặn mã mở đầu sao chép bản ghi vào ngăn xếp cục bộ của hàm. Nói cách khác, 'const' có * không có hiệu lực * ở phía * người gọi của một hàm. Nó chỉ ảnh hưởng đến người nhận cuộc gọi. –

+2

@Rob: Rất tiếc là không thể chỉnh sửa nhận xét. Thật dễ dàng để đọc nhận xét của bạn như thể bạn đang nói rằng các bản ghi luôn được chuyển dưới dạng con trỏ. –

8

Khai báo các kiểu thứ tự const không tạo nên sự khác biệt vì chúng được sao chép (giá trị gọi theo giá trị), vì vậy mọi thay đổi đối với biến không ảnh hưởng đến biến ban đầu.

procedure Foo (Val : Integer) 
begin 
Val := 2; 
end; 
... 
SomeVar := 3; 
Foo (SomeVar); 
Assert (SomeVar = 3); 

IMHO khai báo các loại thứ tự const không có ý nghĩa và như bạn nói yêu cầu bạn giới thiệu biến cục bộ thường xuyên.

+2

Craig có một điểm hợp lệ. Có một lý do chính đáng để khai báo một thứ tự như const; không phải vì lý do hiệu suất. –

16

Bạn không thể vô tình xử lý chúng như thông số var và có mã biên dịch. Vì vậy, nó làm cho ý định của bạn rõ ràng.

+3

Điểm tốt, nhưng không phải là nó đủ để KHÔNG chỉ định một tham số var để làm cho một ý định rõ ràng? – jpfollenius

+2

Smasher, trình biên dịch không phân biệt giữa var và quy ước mặc định trong phạm vi như những gì bạn được phép làm với đối số trong phương thức. –

+1

Ngay cả khi nó có vẻ rõ ràng tại thời điểm này là một giá trị bạn không có ý định thay đổi, nó có thể không sáu tháng sau khi bạn quay trở lại nó, hoặc khi một lập trình viên bảo trì phải nhìn vào mã của bạn. –

1

Nó phụ thuộc vào mức độ phức tạp của thói quen của bạn và cách sử dụng nó. Nếu nó được sử dụng nhiều nơi và yêu cầu giá trị vẫn giữ nguyên, hãy khai báo nó là "const" để làm cho nó bị xóa và an toàn. Đối với loại chuỗi, đã có một lỗi (cho Delphi 7 như tôi stump vào nó) mà gây ra tham nhũng bộ nhớ nếu tuyên bố là "const".Dưới đây là mã mẫu

type 
    TFoo = class 
    private 
    FStr: string; 
    public 
    procedure DoFoo(const AStr: string); 
    begin 
     FStr := AStr; //the trouble code 1 
     ...... 
    end; 
    procedure DoFoo2; 
    begin 
     ..... 
     DoFoo(FStr); //the trouble code 2 
    end; 
    end; 
0

Có một sự cải thiện tốc độ rất lớn sử dụng Const với chuỗi:

function test(k: string): string; 
begin 
    Result := k; 
end; 

function test2(Const k: string): string; 
begin 
    Result := k; 
end; 

function test3(Var k: string): string; 
begin 
    Result := k; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
Var a: Integer; 
    s,b: string; 
    x: Int64; 
begin 
    s := 'jkdfjklf lkjj3i2ej39ijkl jkl2eje23 io3je32 e832 eu283 89389e3jio3 j938j 839 d983j9'; 

    PerfTimerInit; 
    for a := 1 to 10000000 do 
    b := test(s); 
    x := PerfTimerStopMS; 
    Memo1.Lines.Add('default: '+x.ToString); 

    PerfTimerInit; 
    for a := 1 to 10000000 do 
    b := test2(s); 
    x := PerfTimerStopMS; 
    Memo1.Lines.Add('const: '+x.ToString); 

    PerfTimerInit; 
    for a := 1 to 10000000 do 
    b := test3(s); 
    x := PerfTimerStopMS; 
    Memo1.Lines.Add('var: '+x.ToString); 
end; 

mặc định: 443 const: 320 var: 325

mặc định: 444 const: 303 var : 310

mặc định: 444 const: 302 var: 305

Cùng với Số nguyên:

mặc định: 142 const: 13 var: 14

Điều thú vị là mặc dù, trong 64-bit có vẻ là hầu như không có sự khác biệt với chuỗi (chế độ mặc định duy nhất là chậm hơn một chút so với const):

mặc định: 352 const: 313 var: 314

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