Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将普通函数更改为模板将产生任何正/负差异?_C++_Performance_Templates_Inline - Fatal编程技术网

C++ 将普通函数更改为模板将产生任何正/负差异?

C++ 将普通函数更改为模板将产生任何正/负差异?,c++,performance,templates,inline,C++,Performance,Templates,Inline,我有一个包装器函数模板化的外部和核心功能函数作为内部 我设法将编译时常量作为ID传递。因此我考虑将外部原型更改为 template<int ID, typename T> A* Outer (T *p) { return Inner (p, p->value, ID); } 它将被用作 A *pz = Outer<333>(new Z(5)); 想知道,新方法是否会对代码/性能级别产生影响?是否会对内联有任何影响 编辑:ID肯定是在编译时出现的,并且有几个外

我有一个包装器函数模板化的外部和核心功能函数作为内部

我设法将编译时常量作为ID传递。因此我考虑将外部原型更改为

template<int ID, typename T>
A* Outer (T *p)
{
  return Inner (p, p->value, ID);
}
它将被用作

A *pz = Outer<333>(new Z(5));
想知道,新方法是否会对代码/性能级别产生影响?是否会对内联有任何影响


编辑:ID肯定是在编译时出现的,并且有几个外部出现的实例,这就是为什么了解内联也很重要。

首先,由于ID应该是int,所以模板应该是

template<int ID, typename T>
A* Outer (T *p)
...
虽然i是一个变量,但它作为常量值复制到ID

在模板版本中,它们无法写入

int i = 10;
Outer<i, Z>(new Z(5));
由于编译器为ID的每个值生成不同的函数,因此在运行时才知道值的情况下,它不可能在编译时创建函数

因此,您的原始版本更加灵活,而您提出的更改非常严格。我认为大多数人都希望以原始的方式使用函数,而不是强制使用编译时常量。所以我会坚持使用原始的,除非出于某种原因,您真的需要ID值成为编译时常量

编译代码

对于编译后的代码,假设您对至少两个不同的ID值使用该函数,则二进制文件将更大。这是因为会为程序中使用的每个不同的ID值创建一个新函数。因此,如果您希望使用许多不同的值,二进制文件中的膨胀可能会成为一个问题

内联


这件事我没有明确的答案。我猜想,如果内联受到影响,它可能会受到参数T而不是ID的影响。

首先,因为ID应该是int,所以模板应该是int

template<int ID, typename T>
A* Outer (T *p)
...
虽然i是一个变量,但它作为常量值复制到ID

在模板版本中,它们无法写入

int i = 10;
Outer<i, Z>(new Z(5));
由于编译器为ID的每个值生成不同的函数,因此在运行时才知道值的情况下,它不可能在编译时创建函数

因此,您的原始版本更加灵活,而您提出的更改非常严格。我认为大多数人都希望以原始的方式使用函数,而不是强制使用编译时常量。所以我会坚持使用原始的,除非出于某种原因,您真的需要ID值成为编译时常量

编译代码

对于编译后的代码,假设您对至少两个不同的ID值使用该函数,则二进制文件将更大。这是因为会为程序中使用的每个不同的ID值创建一个新函数。因此,如果您希望使用许多不同的值,二进制文件中的膨胀可能会成为一个问题

内联


这件事我没有明确的答案。我猜想,如果内联受到影响,它可能会受到参数T而不是ID的影响。

无。函数是一个模板,因此必须内联,像这样的常量折叠是内联函数时最常见的优化之一。这表明,如果你有一个现代的编译器,它将完全没有任何区别。

无。函数是一个模板,因此必须内联,像这样的常量折叠是内联函数时最常见的优化之一。这表明,如果你有一个现代编译器,它将完全没有任何区别。

假设你做得正确,代码具有相同的功能,那么唯一的惩罚就是编译时间的增加,因为编译模板比编译普通函数需要更长的时间


你可以说我有一台超高速计算机,编译需要1/2秒,但对于大型项目来说这很重要。

假设你做得正确,代码也有同样的功能,那么唯一的惩罚就是编译时间增加,因为编译模板比编译普通函数需要更长的时间


你可以说我有一台超高速计算机,编译需要1/2秒,但对于大型项目来说,这非常重要。

这将取决于你的编译器和函数的使用方式。 实际上,如果你已经找到了优化,那么 我认为您将看到的区别在于调用语法。但如果 您有性能问题,请配置文件并查看问题所在
来自。

它将取决于编译器和函数的使用方式。 实际上,如果你已经找到了优化,那么 我认为您将看到的区别在于调用语法。但如果 您有性能问题,请配置文件并查看问题所在
来自。

你为什么不自己试试呢?虽然乍一看,我看不出你的两个版本会有什么意义

我不知道如何在电脑上试试看。这些函数将出现在代码中的多个位置。我应该比较2编译版本的二进制文件吗?否决的原因是什么?我没有否决你的问题。您可以测试它的一种方法是编写一个测试程序,该程序多次调用这些函数,以及所需的时间。但是,我也看不出有任何性能差异的原因。你为什么不自己试试呢?虽然乍一看,我看不出两个版本在性能上存在显著差异的原因。@silico,我不知道如何尝试。这些函数将出现在代码中的多个位置。我应该比较2编译版本的二进制文件吗?否决的原因是什么?我没有否决你的问题。您可以测试它的一种方法是编写一个测试程序,该程序多次调用这些函数,以及所需的时间。但同样,我看不出有任何性能差异的原因。+1指出int-ID实际上是一个输入错误。谢谢。@iammilind也注意到了用法上的差异。您不能仅使用funcnew类调用它,还必须同时指定funcnew类。所以它甚至比你想要的更硬。@RedX,不需要像你提到的那样调用。funcnew类就足够了。+1用于指出int ID实际上是一个输入错误。谢谢。@iammilind也注意到了用法上的差异。您不能仅使用funcnew类调用它,还必须同时指定funcnew类。所以它甚至比你想要的更硬。@RedX,不需要像你提到的那样调用。funcnew类就足够了。+1,所以更好的内联意味着没有代码膨胀,对吗?专门为我的case@iammilind:在绝大多数情况下,甚至代码膨胀的想法都是荒谬的——在现代标准中,二进制文件的大小非常小。然而,当一个函数内联时,它是内联的,而你传递给它多少模板参数来实现这一点是不相关的。+1,所以更好的内联意味着没有正确的代码膨胀?专门为我的case@iammilind:在绝大多数情况下,甚至代码膨胀的想法都是荒谬的——在现代标准中,二进制文件的大小非常小。然而,当一个函数内联时,它是内联的,而你传递给它多少模板参数来实现这一点是无关紧要的。我非常怀疑编译速度是否会有差异。模板提高编译时间有两个原因:它们显著增加了您需要放入头中的代码量,并且类型推断可能非常昂贵,特别是在更复杂的情况下。这两者都不是问题。@James如果他想将普通函数更改为模板函数,那么他必须在头中实现它们。模板函数的类型推断与模板类的类型推断具有相同的复杂性,不?@VJo他没有将普通函数更改为模板函数。他正在向现有模板添加一个附加参数。类模板没有类型推断,只有函数模板。但在他的例子中,目的是总是明确地指定类型,因此不需要类型推断。我通常赞成限制模板的使用,因为存在耦合,但在这种情况下,考虑到已经有了模板,耦合就在那里,这并不重要。@James我知道我很可能会问一个愚蠢的问题:你确定吗?请看问题的标题:将普通函数更改为模板将产生任何正/负差异?。有了这样的标题,我希望他真的能把一个普通函数变成一个模板函数。@VJo有趣的是,我没有看标题。他在问题中提出的改变是在现有模板中添加一个模板参数。我非常怀疑编译速度是否会有差异。模板提高编译时间有两个原因:它们显著增加了您需要放入头中的代码量,并且类型推断可能非常昂贵,特别是在更复杂的情况下。这两者都不是问题。@James如果他想将普通函数更改为模板函数,那么他必须在头中实现它们。模板函数的类型推断与模板类的类型推断具有相同的复杂性,不?@VJo他没有将普通函数更改为模板函数。他正在向现有模板添加一个附加参数。类模板没有类型推断,只有函数模板。但在他的例子中,目的是总是明确地指定类型,因此不需要类型推断。我通常赞成限制模板的使用,因为存在耦合,但在这种情况下,考虑到已经有了模板,耦合就在那里,这并不重要。@James我知道我很可能会问一个愚蠢的问题:你确定吗?请看问题的标题:更改
模板的正常功能将产生任何正/负差异?。有了这样的标题,我希望他真的能把一个普通函数变成一个模板函数。@VJo有趣的是,我没有看标题。他在问题本身中提出的更改是在现有模板中添加模板参数。
int i = 10;
Outer<i, Z>(new Z(5));