问题
With this code:
struct Point {
x: f64,
y: f64,
}
struct Rectangle {
p1: Point,
p2: Point,
}
impl Rectangle {
pub fn new(x1: f64, y1: f64, x2: f64, y2: f64) -> Rectangle {
let r = Rectangle {
p1: Point { x: x1, y: y1 },
p2: Point { x: x2, y: y2 },
};
// some code where r is used
r
}
}
let rectangle = Rectangle::new(0.0, 0.0, 10.0, 10.0);
From a memory point of view, is rectangle
the same instance as r
, or is it a copy of r
?
Do I have to explicitly return by reference (something like &r
)?
I have to create millions of rectangles, and I don't want there to be useless copies.
回答1:
From a memory point of view, is
rectangle
the same instance asr
, or is it a copy ofr
?
Unspecified.
The Rust language specifies the semantics of the language, and while they do constrain the implementation somewhat, in this case they do not. How a return value is passed up the call stack is part of the ABI, and not only is the ABI unstable (in Rust), it's also platform specific.
Do I have to explicitly return by reference (something like
&r
)?
Returning by reference is not possible.
You could return a Box<Rectangle>
but the cost of the memory allocation would dwarf the cost of copying a Rectangle
in the first place, so it's hardly advisable.
You could force this using output parameters instead, but this has other issues:
- if you have a
&mut Rectangle
parameter, you first need to have a valid instance, which has to be initialized; rather wasteful, - if you have a
*mut Rectangle
pointing to uninitialized memory, you need to useunsafe
code, hardly satisfying.
However...
I have to create millions of rectangles, and I don't want there to be useless copies.
I think you are worrying for nothing.
The first rule of performance tuning is measure first; and I doubt that you'll be able to observe a performance issue in the creation of those millions of rectangles.
The compiler has multiple tricks up its sleeves, such as:
- not even materializing the
rectangle
instance to start with, but pass its components via CPU registers instead, - inlining
new
at the call site, avoiding any copy whatsoever, - ...
Thus, before worrying about the cost of copying 4 f64
, I would implement the naive solution, compile in release mode, and observe what happens.
来源:https://stackoverflow.com/questions/47346001/is-a-returned-value-moved-or-not