我具有函数get_screen
,它是在与main.rs不同的模块中指定的。它需要两个2D向量(一个1920x1080,称为screen
,另一个更大,称为world
),并将world
向量的一部分映射到screen
向量。这是我第一次创建函数签名:
pub fn get_screen(
screen: &mut Vec<Vec<[u8; 4]>>,
world: &Vec<Vec<Chunk>>,
camera_coords: (isize, isize),
screen_width: usize,
screen_height: usize,
chunk_width: usize,
chunk_height: usize,
)
我在执行时间上遇到了严重的问题,但是我使用#[inline]
将执行时间从14ms优化为3ms。
然后我将world
向量移到它自己的结构(以及其他一些相关变量,例如块宽度/高度),并将get_screen
函数变成新的world
结构中的方法。更改后的功能签名如下所示:
pub fn get_screen(
&self,
screen: &mut Vec<Vec<[u8; 4]>>,
camera_coords: (isize, isize),
screen_width: usize,
screen_height: usize,
)
然后执行时间增加到14ms。我曾尝试在Cargo.toml中启用lto=true
并切换到#[inline(always)]
来强制执行它,但似乎编译器拒绝以以前的方式优化此功能。
我试图从结构中删除get_screen
方法,并像以前一样将其作为自己的函数运行,并且似乎可以解决该问题,但是如果我不从中传递任何内容,则只能使用 结构。如果我尝试将usize
结构中的world
传递给单独的get_screen
函数,那么执行时间将从3ms增加到14ms。
要显示我的意思的示例,如果我没有直接从world
结构传递任何内容,而是向它传递了world
中2D结构的克隆版本和硬编码的chunk_width
/ chunk_height
:
gen::get_screen(
&mut screen.buf,
&cloned_world_data,
camera_coords,
SCREEN_WIDTH,
SCREEN_HEIGHT,
CHUNK_WIDTH,
CHUNK_HEIGHT,
);
运行时间为3.3毫秒。当我直接从usize
结构中传递chunk_width
/ chunk_height
字段时:
world
运行需要14.55毫秒
这是怎么回事?在使用gen::get_screen(
&mut screen.buf,
&cloned_world_data,
camera_coords,
SCREEN_WIDTH,
SCREEN_HEIGHT,
world.chunk_width,
world.chunk_height,
);
结构时,如何使get_screen
函数内联编译?最好是,我希望能够将其作为一种方法重新添加到我的World
结构中,而不是将其分开。
这是一个最小的示例:
World
答案 0 :(得分:2)
也许,当您使用world.chunk_width
和world.chunk_height
作为参数时,编译器不会将这些参数视为常量,而是实际上会生成除法和模运算。
另一方面,当您为这些参数提供常量时,它们可以在算法中传播(常量折叠),并且不执行某些昂贵的操作(除法,模数)(或转换为移位/掩码)。
在Godbolt(编译器浏览器)中复制/粘贴代码,将separate_test()
和struct_test()
公开,并使用-C opt-level=3
进行编译可以确认这一点,因为div
指令在为struct_test()
生成了代码,但没有为separate_test()
生成代码。