这个问题的标题可能有点奇怪,但事实是,据我所知,根本没有什么可以反对尾部调用优化.但是,在浏览开源项目时,我已经遇到了一些主动尝试阻止编译器进行尾调用优化的函数,例如CFRunLoopRef的实现,这些函数充满了这样的黑客攻击.例如:
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
if (func) {
func(observer, activity, info);
}
getpid(); // thwart tail-call optimization
}
Run Code Online (Sandbox Code Playgroud)
我很想知道为什么这看起来如此重要,有没有我作为一个普通的开发人员应该保持这种想法呢?例如.尾调用优化有常见的陷阱吗?
c c++ optimization compiler-optimization tail-call-optimization
如今优化似乎是一种迷失的艺术.所有程序员都没有从代码中挤出每一盎司的效率吗?经常在雪地里行走五英里的时候这样做?
本着回归丢失的艺术的精神,您知道的简单(或复杂)变化以优化C#/ .NET代码的一些提示是什么?因为它是如此广泛,取决于一个人想要完成什么,它有助于提供你的提示的背景.例如:
StringBuilder.请参阅底部的链接以了解相关信息.string.Compare两个字符串比较,而不是做这样的事情string1.ToLower() == string2.ToLower()到目前为止,普遍的共识似乎是衡量关键.这种方式忽略了这一点:测量不会告诉你什么是错的,或者如果遇到瓶颈会怎么做.我遇到了字符串连接瓶颈一次,不知道该怎么办,所以这些提示很有用.
我甚至发布这个问题的意思是为了解决常见的瓶颈问题,以及在遇到这些问题之前如何避免它们.它甚至不一定是任何人应该盲目遵循的即插即用代码,而是更多关于获得对性能应该被考虑的理解,至少在某种程度上,并且需要注意一些常见的陷阱.
我可以看到,知道为什么提示有用以及应该应用的位置可能会有用.对于StringBuilder小费,我找到了很久以前在Jon Skeet网站上做过的帮助.
我发现方法的java.lang.Integer实现compareTo如下:
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
Run Code Online (Sandbox Code Playgroud)
问题是为什么使用比较而不是减法:
return thisVal - anotherVal;
Run Code Online (Sandbox Code Playgroud) 在ArrayBlockingQueue,所有需要锁的方法final在调用之前将其复制到局部变量lock().
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
insert(e);
return true;
}
} finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
当字段是什么时,有没有理由复制this.lock到局部变量?lockthis.lockfinal
此外,它还在使用E[]之前使用本地副本:
private E extract() {
final E[] items = this.items;
E x = items[takeIndex];
items[takeIndex] = null;
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
}
Run Code Online (Sandbox Code Playgroud)
有没有理由将最终字段复制到本地最终变量?
我试图为此刷新GCC手册页,但仍然没有得到它,真的.
-march和之间有什么区别-mtune?
什么时候才使用-march,而不是两者兼而有之?是否有可能只是-mtune?
有时我运行Postgres查询需要30秒.然后,我立即运行相同的查询,需要2秒.似乎Postgres有某种缓存.我可以以某种方式看到缓存持有什么?我是否可以强制清除所有缓存以进行调整?
注意:我基本上是在寻找以下SQL Server命令的postgres版本:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
Run Code Online (Sandbox Code Playgroud)
但我还想知道如何查看缓冲区中实际包含的内容.
谢谢你的帮助.
我正在为Android开发游戏.它使用表面视图并使用提供的标准2D绘图API.当我第一次发布游戏时,我正在做各种愚蠢的事情,比如在每个帧上重新绘制9个补丁,同样用文本.我已经通过绘制到Bitmap对象并在每个帧中绘制它们来优化大部分内容,只在需要时重新绘制到Bitmap对象上.
我之前收到过关于电池耗尽的投诉,并且在我修改之后,我想知道(科学地)我是否做了任何改进.不幸的是,我没有任何先前的数据,因此将性能与其他游戏进行比较将是最有用的.
我一直在运行Traceview,并使用它的结果主要是为了识别CPU耗时的方法.
那么 - 确定我的应用程序电池性能的最佳方法是什么,以及什么是良好的基准测试?
我知道我可以通过设置查看不同应用程序的%s,但这又是不科学的,因为我从中得到的数字也取决于所有其他应用程序中发生的情况.我查看了(大部分)谷歌的文档,虽然消息很清楚,你应该节省电池(并且它偶尔提供了如何提示),但几乎没有迹象表明我如何衡量我的应用程序是多么好执行.我想要的最后一件事是更多关于Android Market中电池耗尽的抱怨!
提前致谢.
感谢您提供的所有有用的建议/意见.我真正想知道的是我如何使用来自Traceview的数据(即:在游戏的每个帧上花费的CPU时间)来确定电池使用情况(如果可能的话).回想我原来的问题,我可以看到我有点模糊.再次感谢.
如何在不测量等待锁定释放等的时间的情况下测量查询的执行时间?我唯一的想法是不断测量相同的查询并记录最快的时间.
我让Google告诉我该gcc选项的含义-fomit-frame-pointer,它将我重定向到以下声明.
-fomit帧指针
不要将帧指针保存在寄存器中以查找不需要的函数.这避免了保存,设置和恢复帧指针的指令; 它还在许多功能中提供额外的寄存器.它还使某些机器无法进行调试.
根据我对每个函数的了解,将在进程内存的堆栈中创建激活记录,以保留所有局部变量和更多信息.我希望这个帧指针意味着一个函数的激活记录的地址.
在这种情况下,什么是函数类型,它不需要将帧指针保持在寄存器中?如果我得到这个信息,我会尝试设计基于它的新函数(如果可能),因为如果帧指针没有保存在寄存器中,一些指令将在二进制中省略.在具有许多功能的应用程序中,这将显着提高性能.
是否有可能有一个零执行时间的循环?我认为即使是一个空循环也应该有一个执行时间,因为它有与之相关的开销.
optimization ×10
c ×3
java ×3
c++ ×2
gcc ×2
.net ×1
android ×1
as-if ×1
battery ×1
c# ×1
comparison ×1
final ×1
flags ×1
integer ×1
mysql ×1
options ×1
overflow ×1
performance ×1
postgresql ×1