Tag: 微优化

x> -1 vs x> = 0,是否有性能差异

我听说有一次老师放弃了这个,从那以后一直困扰着我。 假设我们想检查整数x是否大于或等于0.有两种方法可以检查: if (x > -1){ //do stuff } 和 if (x >= 0){ //do stuff } 按照这个老师>会稍微快一点,那么>= 。 在这种情况下,它是Java,但据他说,这也适用于C,C ++和其他语言。 这个陈述有没有道理?

'…!= null'或'null!= …'performance最好?

我写了两种方法来检查性能 public class Test1 { private String value; public void notNull(){ if( value != null) { //do something } } public void nullNot(){ if( null != value) { //do something } } } 并在编译后检查它的字节码 public void notNull(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #2; //Field value:Ljava/lang/String; 4: ifnull 7 7: return LineNumberTable: line […]

将空指针传递给新的位置

默认放置位置new运算符在18.6 [support.dynamic]¶1中用非抛出exception规范声明: void* operator new (std::size_t size, void* ptr) noexcept; 这个函数除了return ptr;外什么也不做return ptr; 所以它是合理的,但是根据5.3.4 [expr.new]¶15这意味着编译器必须检查它在调用对象的构造函数之前不会返回null: -15- [ 注意:除非使用非抛出exception规范(15.4)声明了分配函数,否则它表示抛出std::bad_allocexception来分配存储失败(条款15,18.6.2.1); 否则返回一个非空指针。 如果使用非抛出exception规范声明分配函数,则返回空值以指示分配存储失败,否则返回非空指针。 – 注意 ]如果分配函数返回null,则不进行初始化,不应该调用解除分配函数,new-expression的值应该为空。 在我看来,(特别是安置new ,不是一般的)这个空检查是一个不幸的performance打击,尽pipe很小。 我一直在debugging一些代码,其中放置new被用在一个性能敏感的代码path中,以改善编译器的代码生成,并且在程序集中检查了null。 通过提供一个特定于类的放置位置的new重载,这个重载是通过抛出的exception规范来声明的(即使它不可能抛出),条件分支也被移除了,这也允许编译器为周围的内联函数生成更小的代码。 说安置newfunction的结果可能会抛出,尽pipe它不能 ,是明显更好的代码。 所以我一直想知道是否真的需要空位检查new情况下安置。 它可以返回null的唯一方法是如果你通过它null。 虽然这是可能的,而且显然是合法的,写: void* ptr = nullptr; Obj* obj = new (ptr) Obj(); assert( obj == nullptr ); 我不明白为什么这将是有用的,我build议,如果程序员必须在使用安置之前明确地检查空 Obj* obj = ptr ? new (ptr) […]

Python中的exception处理程序的代价

在另一个问题中 ,接受的答案build议用try / except块replacePython代码中的(非常便宜的)if语句以提高性能。 除了编码风格的问题,假设exception没有被触发,它有多less差异(性能方面)有一个exception处理程序,而不是一个,而不是一个比较为零的if语句?

在`typeid`代码中使用'?:`奇怪

在我正在开发的其中一个项目中,我看到了这个代码 struct Base { virtual ~Base() { } }; struct ClassX { bool isHoldingDerivedObj() const { return typeid(1 ? *m_basePtr : *m_basePtr) == typeid(Derived); } Base *m_basePtr; }; 我从来没有见过像那样使用typeid 。 为什么这么奇怪的跳舞?: ,而不是只是做typeid(*m_basePtr) ? 有什么理由吗? Base是一个多态类(具有虚拟析构函数)。 编辑:在这个代码的另一个地方,我看到这个,它似乎是等价的“多余的” template<typename T> T &nonnull(T &t) { return t; } struct ClassY { bool isHoldingDerivedObj() const { return typeid(nonnull(*m_basePtr)) == […]

什么时候循环展开仍然有用?

我一直试图通过循环展开来优化一些极其关键的性能问题代码(在蒙特卡洛模拟中被称为数百万次的快速sortingalgorithm)。 这里是我试图加速的内部循环: // Search for elements to swap. while(myArray[++index1] < pivot) {} while(pivot < myArray[–index2]) {} 我试图展开到像这样的东西: while(true) { if(myArray[++index1] < pivot) break; if(myArray[++index1] < pivot) break; // More unrolling } while(true) { if(pivot < myArray[–index2]) break; if(pivot < myArray[–index2]) break; // More unrolling } 这完全没有区别,所以我把它改回到更易读的forms。 其他时候我也有类似的经历,我试过循环展开。 鉴于现代硬件上的分支预测器的质量,何时循环展开仍然是一个有用的优化?

执行范围检查通过投射到uint而不是检查负值是否更有效?

我偶然发现了.NET的List源代码中的这段代码 : // Following trick can reduce the range check by one if ((uint) index >= (uint)_size) { ThrowHelper.ThrowArgumentOutOfRangeException(); } 显然这比if (index < 0 || index >= _size)更有效率(? if (index < 0 || index >= _size) 我很好奇背后的理由。 单个分支指令是否比两个转换为uint更昂贵? 还是有一些其他的优化,会使这个代码比另一个数字比较更快? 为了解决房间里的大象:是的,这是微型优化,不,我不打算在我的代码中到处使用它 – 我只是好奇;)

从Javastring中去除所有不可打印字符的最快方法

什么是从Java中的String中去除所有不可打印字符的最快方法? 到目前为止,我已经尝试和测量了138字节,131字符的string: String的replaceAll() – 最慢的方法 517009结果/秒 预编译模式,然后使用匹配器的replaceAll() 637836结果/秒 使用StringBuffer,使用codepointAt()逐个获取代码codepointAt()并追加到StringBuffer 711946结果/秒 使用StringBuffer,使用charAt()逐个获取字符并追加到StringBuffer 1052964结果/秒 预先分配一个char[]缓冲区,使用charAt()逐个获取字符并填充此缓冲区,然后转换回string 2022653结果/秒 预先分配2个char[]缓冲区 – 旧的和新的,使用getChars()立即获取现有string的所有字符, getChars()迭代旧缓冲区并填充新缓冲区,然后将新缓冲区转换为string – 我自己的最快版本 每秒2502502个结果 与2缓冲区相同的东西 – 只使用byte[] , getBytes()和指定编码为“utf-8” 857485结果/秒 与2 byte[]缓冲区相同的东西,但指定编码作为一个常量Charset.forName("utf-8") 791076结果/秒 与2 byte[]缓冲区相同的东西,但指定编码为1字节的本地编码(只是一个理智的事情) 370164结果/秒 我最好的尝试是以下几点: char[] oldChars = new char[s.length()]; s.getChars(0, s.length(), oldChars, 0); char[] newChars = new char[s.length()]; int newLen = 0; for (int j […]

为什么我的应用程序花费24%的生命做空检查?

我有一个性能重要的二叉决策树,我想把这个问题集中在一行代码上。 二叉树迭代器的代码如下,运行性能分析的结果。 public ScTreeNode GetNodeForState(int rootIndex, float[] inputs) { 0.2% ScTreeNode node = RootNodes[rootIndex].TreeNode; 24.6% while (node.BranchData != null) { 0.2% BranchNodeData b = node.BranchData; 0.5% node = b.Child2; 12.8% if (inputs[b.SplitInputIndex] <= b.SplitValue) 0.8% node = b.Child1; } 0.4% return node; } BranchData是一个字段,而不是一个属性。 我这样做是为了防止不被内联的风险。 BranchNodeData类如下所示: public sealed class BranchNodeData { /// <summary> /// The […]

哪个更好的select用于除以2的整数?

以下哪种技术是将整数除以2的最佳select,为什么? 技术1: x = x >> 1; 技术2: x = x / 2; 这里x是一个整数。