如何通过.NET高效实现Structure返回值优化策略?

2026-05-06 09:171阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计791个文字,预计阅读时间需要4分钟。

如何通过.NET高效实现Structure返回值优化策略?

在考虑一个返回结构体的函数时,如示例所示:

vbPublic Function DoWork() As MyStructure Return New MyStructure(1.5, 1.7, 1.1, 55.9)End Function

在.NET中,对于`MyStructure`的创建和初始化,以下情况可能发生:

1. 单次创建和初始化:如果`MyStructure`是一个值类型,并且这个函数是第一次创建`MyStructure`实例,那么.NET编译器可能会优化这个操作,只创建并初始化一次。

2. 多次创建和初始化:如果`MyStructure`的实例在其他地方被引用或者有多个引用,那么每次调用`DoWork`函数时,都可能创建一个新的实例并初始化它。

3. 静态构造函数:如果`MyStructure`有静态构造函数,那么即使函数不创建实例,静态构造函数也可能被调用。

总结来说,是否创建和初始化`MyStructure`一次或多次取决于它的类型(值类型或引用类型)、引用计数以及是否定义了静态构造函数。

考虑一个返回结构的方法,如下所示:

Public Function DoWork() As MyStructure Return New MyStructure(1.5, 1.7, 1.1, 55.9) End Function

在这种情况下,.NET是否创建并初始化MyStructure值一次或两次?

编辑:我的预感是,对DoWork的调用必须涉及.NET从一开始就在堆栈上推送返回值.否则,Return会如何回复调用代码?所以这是我正在谈论的第一次初始化.

如何通过.NET高效实现Structure返回值优化策略?

第二个初始化将在Return语句中,其中参数1.5,1.7,1.1,55.9初始化一个新的MyStructure值.在返回时,.NET将使用新的返回值覆盖Stack上的现有值.

问题是,我对.NET的工作原理知之甚少.我对Stacks如何工作的概念是基于在DOS下,在80年代早期尝试在Pascal中编码的模糊回忆.我不知道.NET / Windows如何做这些事情!

只需看看生成的机器代码,看看会发生什么.您首先需要更改选项以确保启用优化程序,工具>选项>调试>一般>取消勾选“抑制JIT优化”复选框.切换到发布版本.在DoWork调用上设置断点,当它命中时使用Debug> Windows>反汇编以查看生成的机器代码.

关于你所看到的,我会面对一点.你的直觉是正确的,只返回简单的标量值是有效的,它们适合CPU寄存器.不是这种结构,调用方法必须在其堆栈帧上保留空间,以便被调用者可以在那里存储结构.它传递指向该保留空间的指针.换句话说,如果您将此方法声明为Public Sub DoWork(ByRef retval As MyStructure),则没有实际区别.

只有通过内联函数,才能优化此代码的其他方式. x86抖动不会这样做,它对返回结构的方法很挑剔.事实上,x64抖动实际上是内联方法,但随后它完成了一个绝对可怕的工作.它仍然保留返回值的空间,然后生成许多不必要的初始化和值移动代码.非常残忍.这个抖动被重写为VS2015(项目名称RyuJIT),我还没有安装它,看它是否做得更好.

绘制的基本结论:此代码未优化.传递ByVal时,结构运行良好.不要让这个痉挛你的风格,我们在这里谈论纳秒.

标签:方法

本文共计791个文字,预计阅读时间需要4分钟。

如何通过.NET高效实现Structure返回值优化策略?

在考虑一个返回结构体的函数时,如示例所示:

vbPublic Function DoWork() As MyStructure Return New MyStructure(1.5, 1.7, 1.1, 55.9)End Function

在.NET中,对于`MyStructure`的创建和初始化,以下情况可能发生:

1. 单次创建和初始化:如果`MyStructure`是一个值类型,并且这个函数是第一次创建`MyStructure`实例,那么.NET编译器可能会优化这个操作,只创建并初始化一次。

2. 多次创建和初始化:如果`MyStructure`的实例在其他地方被引用或者有多个引用,那么每次调用`DoWork`函数时,都可能创建一个新的实例并初始化它。

3. 静态构造函数:如果`MyStructure`有静态构造函数,那么即使函数不创建实例,静态构造函数也可能被调用。

总结来说,是否创建和初始化`MyStructure`一次或多次取决于它的类型(值类型或引用类型)、引用计数以及是否定义了静态构造函数。

考虑一个返回结构的方法,如下所示:

Public Function DoWork() As MyStructure Return New MyStructure(1.5, 1.7, 1.1, 55.9) End Function

在这种情况下,.NET是否创建并初始化MyStructure值一次或两次?

编辑:我的预感是,对DoWork的调用必须涉及.NET从一开始就在堆栈上推送返回值.否则,Return会如何回复调用代码?所以这是我正在谈论的第一次初始化.

如何通过.NET高效实现Structure返回值优化策略?

第二个初始化将在Return语句中,其中参数1.5,1.7,1.1,55.9初始化一个新的MyStructure值.在返回时,.NET将使用新的返回值覆盖Stack上的现有值.

问题是,我对.NET的工作原理知之甚少.我对Stacks如何工作的概念是基于在DOS下,在80年代早期尝试在Pascal中编码的模糊回忆.我不知道.NET / Windows如何做这些事情!

只需看看生成的机器代码,看看会发生什么.您首先需要更改选项以确保启用优化程序,工具>选项>调试>一般>取消勾选“抑制JIT优化”复选框.切换到发布版本.在DoWork调用上设置断点,当它命中时使用Debug> Windows>反汇编以查看生成的机器代码.

关于你所看到的,我会面对一点.你的直觉是正确的,只返回简单的标量值是有效的,它们适合CPU寄存器.不是这种结构,调用方法必须在其堆栈帧上保留空间,以便被调用者可以在那里存储结构.它传递指向该保留空间的指针.换句话说,如果您将此方法声明为Public Sub DoWork(ByRef retval As MyStructure),则没有实际区别.

只有通过内联函数,才能优化此代码的其他方式. x86抖动不会这样做,它对返回结构的方法很挑剔.事实上,x64抖动实际上是内联方法,但随后它完成了一个绝对可怕的工作.它仍然保留返回值的空间,然后生成许多不必要的初始化和值移动代码.非常残忍.这个抖动被重写为VS2015(项目名称RyuJIT),我还没有安装它,看它是否做得更好.

绘制的基本结论:此代码未优化.传递ByVal时,结构运行良好.不要让这个痉挛你的风格,我们在这里谈论纳秒.

标签:方法