这是一段看似非常特殊的C++代码.出于某种奇怪的原因,奇迹般地对数据进行排序使得代码几乎快了六倍.
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster.
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c) …
Run Code Online (Sandbox Code Playgroud) 引自http://sites.google.com/site/gson/gson-design-document:
为什么Gson中的大多数课程都被标记为最终?
虽然Gson通过提供可插拔序列化器和反序列化器提供了相当可扩展的架构,但Gson类并未专门设计为可扩展.提供非最终类将允许用户合法地扩展Gson类,然后期望该行为在所有后续修订中工作.我们选择通过将类标记为final来限制这样的用例,并等到出现良好的用例以允许扩展性.标记类final也有一个很小的好处,即为Java编译器和虚拟机提供额外的优化机会.
为什么会这样?[如果我猜测:JVM知道类是最终的,它不维护方法覆盖表?还有其他原因吗?]
性能有什么好处?
这是适用于频率实例化的类(POJO?)还是适用于持有静态方法(实用类)的类?
定义为final的方法在理论上也可以提高性能吗?
有什么影响吗?
谢谢你,马克西姆.
我有一些经过大量优化的数学函数需要1-2 nanoseconds
完成.这些功能每秒被称为数亿次,因此尽管性能已经非常出色,但呼叫开销仍是一个问题.
为了保持程序的可维护性,提供这些方法的类继承了一个IMathFunction
接口,以便其他对象可以直接存储特定的数学函数并在需要时使用它.
public interface IMathFunction
{
double Calculate(double input);
double Derivate(double input);
}
public SomeObject
{
// Note: There are cases where this is mutable
private readonly IMathFunction mathFunction_;
public double SomeWork(double input, double step)
{
var f = mathFunction_.Calculate(input);
var dv = mathFunction_.Derivate(input);
return f - (dv * step);
}
}
Run Code Online (Sandbox Code Playgroud)
由于消费代码使用它,这种接口与直接呼叫相比造成了巨大的开销.一个直接调用需要1-2ns,而虚拟接口调用需要8-9ns.显然,接口的存在及其随后的虚拟呼叫转换是这种情况的瓶颈.
如果可能的话,我想保留可维护性和性能.有没有办法在实例化对象时将虚函数解析为直接调用,以便所有后续调用都能够避免开销?我认为这将涉及用IL创建委托,但我不知道从哪里开始.
我只是想知道,因为密封关键字的存在表明它是类作者关于是否允许其他类继承它的决定,为什么默认情况下没有类密封,有一些关键字将它们显式标记为可扩展?
我知道它有些不同,但访问修饰符以这种方式工作.默认情况下是限制性的,只有通过插入关键字才能获得更全面的访问权限.
尽管如此,我很有可能没有想到这一点,所以请保持人性化!
密封课程不是我过去常常注意到的事情,但我发现自己想知道什么是最佳实践.如果你知道一个课程不会或不应该从中得出你是否会密封它作为一个预防措施,只需留下密封的关键字,知道有人试图从中获取的机会很小.
我想我要问的是,你是否应该密封所有不用于继承的课程,只是作为一种良好的做法?
python是否有类似于密封类的东西?我相信它在java中也被称为final类.
换句话说,在python中,我们可以标记一个类,以便它永远不会被继承或扩展吗?python曾经考虑过有这样的功能吗?为什么?
实际上试图理解为什么密封课程甚至存在.答案在这里(和很多,很多,很多,很多,很多,真的很多其他地方)没有满足我的人,所以我试图从不同的角度看.请避免对这个问题的理论答案,并专注于标题!或者,如果你坚持,至少请给出csharp中密封类的一个非常好的实用例子,指出如果它是未密封的话会破坏大的时间.
我不是两种语言的专家,但我确实知道两种语言.就在昨天,在使用csharp进行编码时,我了解了密封类的存在.现在我想知道python是否有相同的东西.我相信它的存在是有充分理由的,但我真的没有得到它.
可能重复:
密封类真的提供性能优势吗?
我的团队正在内部与密封的课堂辩论进行斗争,我想将辩论简化为设计问题,并将性能神话从辩论议程中删除.
任何人都可以发布一些代码来证明通过将类声明为密封而引入的性能提升吗?每秒2000万次虚拟方法调用,我看不到多少好处,可能在1000万次迭代中有1或2毫秒,但即便如此,我也不确定,因为结果会跳转.这适用于调试和发布运行.
ps我跟随一些John Skeet获得了关于密封类设计的好处的智慧,特别是当软件是通过团队或组织边界交付和/或类是组件中的打包组件样式时.
如果一个类没有任何虚方法,我认为继承类的任何方式都不会影响任何未明确引用该实例作为子类实例的代码,即
Subclass obj = new Subclass()
Run Code Online (Sandbox Code Playgroud)
而不是
BaseClass obj = new SubClass()
Run Code Online (Sandbox Code Playgroud)
因此,为什么sealed
甚至存在?
如果你没有声明任何东西virtual
(我认为在密封类中没有任何意义),它会阻止像(例如)a ListViewItem
那样存储一些关于它代表什么的额外信息的代码"知道"该信息是在那里,与重写的方法不同,它对没有用该子类编写的代码没有影响.
c# ×5
sealed ×4
.net ×3
class ×2
inheritance ×2
java ×2
oop ×2
optimization ×2
performance ×2
c++ ×1
cil ×1
final ×1
jvm ×1
python ×1
reflection ×1