2011-06-20 6 views
10

Tôi đang làm việc với giải pháp của mình cho vấn đề Cult of the Bound Variable.Làm cách nào để tăng tốc nhân bản mảng trong C#?

Một phần của sự cố khi bạn triển khai phiên dịch cho Máy phổ quát "cổ đại". Tôi đã thực hiện một intepreter cho máy họ mô tả và bây giờ tôi đang chạy một chương trình chuẩn mà trường đại học cung cấp để kiểm tra nó.

Việc triển khai C# của tôi cho người phiên dịch này là chậm!

Tôi đã kích hoạt chương trình trong trình thu thập ANTS để xem sự chậm lại và tôi có thể thấy rằng trên 96% thời gian của tôi được thực hiện bởi hoạt động "Tải chương trình".

ANTS Profile Results

Các specification của toán tử này như sau:

#12. Load Program. 

       The array identified by the B register is duplicated 
       and the duplicate shall replace the '0' array, 
       regardless of size. The execution finger is placed 
       to indicate the platter of this array that is 
       described by the offset given in C, where the value 
       0 denotes the first platter, 1 the second, et 
       cetera. 

       The '0' array shall be the most sublime choice for 
       loading, and shall be handled with the utmost 
       velocity. 

Đây là mã của tôi cho toán tử này:

case 12: // Load Program 
    _platters[0] = (UInt32[])_platters[(int)_registers[B]].Clone(); 
    _finger = _registers[C]; 
    break; 

Mã nguồn cho toàn bộ "Universal Machine" của tôi thông dịch viên là here.

Tôi có thể làm gì để làm điều này nhanh hơn? Có những triển khai khác của thông dịch viên này được viết bằng C, hoàn thành toàn bộ điểm chuẩn nhanh hơn đáng kể.

+1

Bạn có thể cung cấp các loại cho _platters và các thành viên khác không? Hãy thử Array.Copy, Buffer.BlockCopy hoặc con trỏ. –

+0

@ lukas, tôi đã cung cấp liên kết tới trang github có cả lớp trong đó. Nhưng _platters là một Danh sách . – mmcdole

+0

Vì vậy, ngoài sự tò mò, tốc độ đạt được bằng cách sử dụng câu trả lời được chấp nhận là gì? Câu hỏi của bạn sẽ trở nên có giá trị hơn đối với những người dùng SO khác – sehe

Trả lời

6

Bạn có thể thử sử dụng Buffer.BlockCopy, mặc dù tôi sẽ ngạc nhiên nếu nó làm cho bất kỳ sự khác biệt lớn trong trường hợp này:

case 12: // Load Program 
    uint[] src = _platters[(int)_registers[B]]; 
    _platters[0] = new uint[src.Length]; 
    Buffer.BlockCopy(src, 0, _platters[0], 0, src.Length * 4); 
    _finger = _registers[C]; 
    break; 
0

Tùy thuộc vào cách là hai mảng kết quả được sử dụng, bạn có thể sử dụng sửa đổi copy-on-write:

Bạn sẽ không sử dụng trực tiếp mảng, nhưng sử dụng trình bao bọc. Để sao chép một mảng, chỉ cần tạo một trình bao bọc khác. Nếu bạn cố gắng ghi vào một mảng được chia sẻ bởi nhiều trình bao bọc, bạn thực hiện nhân bản thực tế và tách các trình bao bọc.

0

Bên cạnh những câu hỏi trong tầm tay, lý do thực VM tiêu chuẩn của bạn để kém là bạn nên xử lý 0 "với vận tốc tối đa" như spec nói;)

Về cơ bản, nhảy thường xuyên được thực hiện bằng cách làm một tải từ 0 đến 0. Điều này là cực kỳ phổ biến trong mã codex. Bạn nên tránh nhân bản hoàn toàn và chỉ cập nhật "ngón tay" trong trường hợp cụ thể đó.