问题标签 [micro-optimization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 重复文字和硬编码
我看到以下模式经常发生:
请注意,文字字符串被使用了两次。提取物来自 nginx 源代码库。
当在编译单元中遇到这些文字时,编译器应该能够合并这些文字。
我的问题是:
- 在编译单元中遇到商业级编译器(VC++、GCC、LLVM/Clang)是否会消除这种冗余?
- (静态)链接器在链接目标文件时是否删除了此类冗余。
- 如果 2 适用,这种优化会在动态链接期间发生吗?
- 如果 1 和 2 适用,它们是否适用于所有文字。
这些问题很重要,因为它允许程序员在不损失效率的情况下变得冗长——例如,考虑将大量静态数据模型硬连接到程序中(例如,在某些低级场景中使用的决策支持系统的规则) .
编辑
2 点/说明
上面的代码是由公认的“大师”程序员编写的。那家伙单枪匹马写了nginx。
我没有问过哪种可能的文字硬编码机制更好。因此,不要跑题。
编辑 2
我最初的例子是相当做作和限制性的。以下代码段显示了嵌入到内部硬编码知识中的字符串文字的用法。第一个片段用于配置解析器,告诉它要为哪个字符串设置哪些枚举值,第二个片段更普遍地用作程序中的字符串。只要编译器使用字符串文字的一份副本,我个人对此感到满意,并且由于元素是静态的,它们不会进入全局符号表。
紧随其后的是:
对于那些留在主题上的人,太棒了!
assembly - 清除 PF(奇偶校验标志)的一条指令——在结果寄存器中获取奇数位
在 x86 汇编中,是否可以在一条且仅一条指令中清除奇偶校验标志,在任何初始寄存器配置下工作?
这等效于使用任何设置标志的操作(明确排除)创建具有奇数mov
位的结果寄存器。
相比之下,设置奇偶校验标志可以在一条指令中完成:
并且有很多方法可以用两条指令清除奇偶校验标志:
然而,单一指令的方法仍然难以捉摸。
assembly - Intel 8086 Assembly -- Squaring a Register
In principle, squaring the value of a register isn't hard:
But I got to thinking -- the course that I'm learning Assembly for prizes efficiency very highly; a difference of even a single line less could be worth up to 5 points.
I realize this is micro-optimization, but would the following code perform the the same way?:
I suppose a much simpler way of expressing my question: is AX (or AL/AH) a valid parameter for the mul
and imul
commands in 8086 assembly?
c# - 如何测试哪种方法实现运行得更快
虽然检查输入是否为字符串类型的问题已关闭,但其中两个答案在我脑海中引发了一个微优化问题:以下两种解决方案中哪一种表现更好?
Reed Copsey提供了一个解决方案,使用Char.IsLetter
:
使用来自Mark Byers的正则表达式改编的解决方案:
不想只问 Reed 或 Mark 的问题,我想我会写一个快速测试来确定哪个表现更好。问题是我没有做很多代码优化(我倾向于把代码可读性放在首位)。
除了在每个运行之前和之后获取时间戳之外,还有哪些其他(更好的?)选项可以确定哪个解决方案运行得更快?
编辑
我修改了Martin 的答案以使用Console.WriteLine(...)
并将其作为控制台应用程序运行。不确定LinqPad如何运行应用程序,但结果大致相同:
c - 使用两个循环体还是一个(结果相同)?
我一直想知道在更好地利用 CPU 缓存方面什么更有效(众所周知,这会受益于引用的局部性)——两个循环,每个循环都迭代相同的数学数字集,每个循环都有不同的主体语句(例如为集合的每个元素调用一个函数),或者有一个循环,其主体相当于两个(或多个)主体语句。在所有循环之后,我们假设相同的应用程序状态。
在我看来,有两个循环会引入更少的缓存未命中和驱逐,因为循环使用的更多指令和数据适合缓存。我对吗?
假设:
与循环的成本相比
f
,调用的成本可以忽略不计g
f
并g
单独使用大部分缓存,因此当一个又一个被调用时缓存会溢出(单循环版本的情况)英特尔酷睿双核 CPU
C语言源代码
GCC 编译器,“没有额外的开关”
如果可能的话,我想要“过早的优化是邪恶的”角色之外的答案。
我提倡的双循环版本的一个示例:
java - 这两个 Java 段的性能有什么不同吗?
我很想知道这两个 Java 方法调用中的任何一个在处理器时间、内存分配和/或垃圾收集方面的行为是否完全不同。
对比
c++ - 关于循环速度的问题
我有以下两个循环:
我跑了三遍。在前两次运行中,第二次循环最快,但在第三次运行中,第一次循环最快。这是什么意思?哪个更好?这取决于情况吗?
c# - 优化查找
我有一个用于查找值的数组。我使用前 2 个值来获取 n 行。例如,所有行在第一列有 2,在第二列有 7。 获得这些值的最快(我的意思是微优化)方法是什么? 我现在使用 for 循环来获取值:
编辑: 它只有大约 60 行。如果我创建 3 个嵌套数组,那么我可以像 t[2][7] 一样直接使用前 2 列作为索引,然后我只会遍历我真正需要的行。那会更快吗?
桌子:
sql - 创建为 FULLTEXT 搜索优化的第二列有什么意义吗?
我正在处理的项目对于需要搜索的每一列都有一个名为“ft[columnname]”的第二列,它有一个 FULLTEXT 索引,并且只搜索这一列。
此列包含一个“优化”文本,它是通过以下方式从原始列自动生成的:
- 字符串是小写的
- 删除所有重音
- 删除所有标点符号和无法搜索的字符
- 所有重复的单词都被删除
- 所有单词从最长到最短排序
- 我不太了解的其他转换(与组合词有关)
例如“我喜欢神奇宝贝,尤其是皮卡丘!” 变成“特别是像我这样的口袋妖怪皮卡丘”。
是否有任何(甚至是非常小的)性能优势?数据库中的数据永远不会动态变化。
c - 微优化:将 intptr_t 用于标志/布尔类型
据我了解, intptr_t 的定义因架构而异——它保证能够表示一个指针,该指针可以访问进程的所有统一地址空间。
Nginx(流行的开源网络服务器)定义了一个用作标志(布尔值)的类型,这是一个 typedef 到intptr_t
. 现在以 x86-64 架构为例——它可以访问涵盖所有大小操作数的大量指令——为什么将标志定义为 intptr_t ?当然,使用 32 位 bool 类型的传统也符合要求吗?
我已经了解了 32 位 Vs。当我还是一名新开发人员时,我自己争论 8 位布尔值,结论是由于处理器设计的复杂性,32 位布尔值在常见情况下表现更好。那么为什么需要转移到 64 位 bools 呢?