2016-02-11 19 views
5

Câu hỏi của tôi là có hay không một bản sao của một giá trị được thực hiện khi một phương thức được gọi tại nơi _ là người nhận.Bộ nhận `_` trên giá trị (không có con trỏ) vẫn sao chép giá trị?

type Foo struct { 
    // Many fields, making a large struct 
} 

func (_ Foo) Test(v *T) int { 
    // Here we can't use the receiver but the method is still needed 
} 

Vì vậy, tôi tự hỏi nếu Go triển khai vẫn sẽ sao chép các giá trị Foo khi Test() được gọi, mặc dù nó không thể thực sự đột biến giá trị nhận.

var f Foo 
f.Test() // Is this making a copy? 

Tôi cũng sẽ tự hỏi về trường hợp con trỏ, được tự động bỏ qua theo mặc định.

var f = new(Foo) 
f.Test() // Is this making a copy? 

Tôi đã thử nhìn vào hội đồng, và tôi nghĩ rằng nó có thể làm cho bản sao, nhưng tôi chỉ không biết đủ để chắc chắn.


Để biết chi tiết về tình hình:

Đây là một trường hợp kỳ lạ mà tôi không thể sử dụng một con trỏ. Mã được tạo ra và được yêu cầu để tạo ra một loại để hoàn thành một giao diện trong khi thực hiện một số khởi tạo trên tham số v. (Các mã được tạo có siêu dữ liệu về Foo đó được đặt trên v.)

Vì vậy, nếu tôi làm cho người nhận một con trỏ, giao diện sẽ không được thực hiện cho các trường hợp "giá trị". Phương thức này sẽ được gọi một lần cho mỗi cá thể, và các cá thể đôi khi có thể lớn và/hoặc được tạo ra với số lượng lớn, đó là lý do tại sao tôi muốn tránh một bản sao không cần thiết.

+1

thể kiểm tra bằng cách làm cho một loại máy thu khổng lồ ('loại lớn [1e5] int' hoặc bất cứ điều gì), cách gọi một phương pháp như của bạn một triệu lần, và nhìn thấy nếu nó chạy chậm hơn đáng kể so với làm điều tương tự với một loại máy thu nhỏ hơn. – twotwotwo

+2

Chuỗi công cụ gc không tối ưu hóa trường hợp đối số được đặt tên bằng mã định danh trống. –

+1

Tôi đang xóa câu trả lời trừ khi tôi có thời gian để kiểm tra lắp ráp và xem sự khác biệt thực sự là gì, vì việc tiết kiệm ~ 4ns ít hơn tiếng ồn thống kê của bất kỳ công việc thực tế nào. Nói chung, CPU rất nhanh khi sao chép, vì vậy bạn không nên lo lắng về điều này trừ khi cấu trúc của bạn rất lớn. Trong trường hợp đó chỉ cần sử dụng một con trỏ, vì bạn sẽ không trả giá tra cứu nếu bạn không dereference nó. – JimB

Trả lời

3

Theo this blog post, người gọi phân bổ các yếu tố ngăn xếp cho các giá trị trả lại và callee điền chúng.

Điều này khiến tôi tin rằng giá trị được sao chép và sau đó bị hủy.

Đó hoặc một callee chuyên ngành sẽ phải được tạo ra trong trường hợp của _ nhận

+0

Cảm ơn, có nó xuất hiện từ thử nghiệm rằng giá trị thực sự được sao chép.Có vẻ như một tối ưu hóa an toàn để tránh các bản sao, nhưng vì nó là một trường hợp bất thường, nó không làm tôi ngạc nhiên quá nhiều mà tối ưu hóa này không tồn tại. –

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