IMO肯定的,但对于更大的环状图形的一个小例子基本的设计原因比虚拟调度或COM类接口查询或运行时类型信息所需的对象元数据或类似的东西更加微妙和复杂。所有这些都有相关的开销,但它在很大程度上取决于所使用的语言和编译器,还取决于优化程序是否可以在编译时或链接时消除这种开销。然而,在我看来,有一个更广泛的概念之所以编码到一个接口蕴含(非保证)性能的下降:
编码到一个接口意味着有你和 之间的屏障你想要的具体数据/存储访问和转换。
这是我看到的主要原因。作为一个非常简单的例子,假设您有一个抽象图像接口。它完全抽象出其像素格式的具体细节。这里的问题是,最高效的图像操作通常需要那些具体的细节。我们无法使用高效的SIMD指令来实现我们的定制图像过滤器,例如,如果我们必须一次一个地删除getPixel
,并且一次只删除一个,而忽略底层的像素格式。
当然,抽象图像可以尝试提供所有这些操作,并且这些操作可以非常有效地实现,因为它们可以访问实现该接口的具体图像的私有内部细节,但只能作为只要图像界面提供客户想要对图像执行的所有操作。
通常在某些时候,界面不能希望为整个世界提供可想象的每个功能,所以当遇到性能关键问题而同时需要满足广泛的需求时,这些界面经常会泄漏它们的混凝土细节。抽象图像仍然可以通过一个pixels()
方法提供一个指向其底层像素的指针,这个方法在很大程度上破坏了接口编码的许多目的,但在大多数性能关键领域通常都是必需的。
一般来说,很多最高效的代码通常必须针对某些级别的非常具体的细节进行编写,例如专门为单精度浮点编写的代码,专门为32位RGBA图像编写的代码,代码这是专门为GPU编写的,专门针对AVX-512,特别是针对移动硬件等。所以这是一个基本的障碍,至少对于我们迄今为止所使用的工具,我们无法将其全部抽象出来,只是将代码编码到一个没有暗示的接口罚款。
当然,如果我们可以编写代码,忘记所有这些具体细节,例如我们是在处理32位SPFP还是64位DPFP,我们是不是正在编写着色器,我们的生活就会变得如此简单有限的移动设备或高端桌面,并且它们都是最有竞争力的代码。但我们离这个阶段还很远。我们目前的工具仍然经常要求我们针对具体细节编写我们的性能关键代码。
最后,这是一个粒度问题。当然,如果我们必须逐个像素地处理事物,那么任何试图抽象出像素的具体细节的尝试都可能导致性能损失。但是,如果我们在图像层面上表达事物,例如“alpha将这两个图像混合在一起”,那么即使存在虚拟调度开销等等,这也可能是微不足道的成本。因此,当我们向更高级别的代码努力时,编码到接口的任何暗示性能损失都会减少到变得完全无关紧要的程度。但总是需要低级代码,它像逐个像素一样处理事物,每帧循环数百万次,并且编码到接口的代价可以带有漂亮的效果如果仅仅是因为它隐藏了写出最有效实施所必需的具体细节,那么将会受到重大的惩罚。
你的问题仍然有效,但你错误地引用了这个人。他在说,提供接口*仅仅是为单元测试提供模拟方式*并不值得。我可以看到他的观点。 – 2009-05-06 08:20:46
我不知道。它可以提供多少击打?什么是值得你能够测试的东西? – 2009-05-06 10:05:28