问题标签 [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.

0 投票
5 回答
1862 浏览

c++ - 重复文字和硬编码

我看到以下模式经常发生:

请注意,文字字符串被使用了两次。提取物来自 nginx 源代码库。

当在编译单元中遇到这些文字时,编译器应该能够合并这些文字。

我的问题是:

  1. 在编译单元中遇到商业级编译器(VC++、GCC、LLVM/Clang)是否会消除这种冗余?
  2. (静态)链接器在链接目标文件时是否删除了此类冗余。
  3. 如果 2 适用,这种优化会在动态链接期间发生吗?
  4. 如果 1 和 2 适用,它们是否适用于所有文字。

这些问题很重要,因为它允许程序员在不损失效率的情况下变得冗长——例如,考虑将大量静态数据模型硬连接到程序中(例如,在某些低级场景中使用的决策支持系统的规则) .

编辑

2 点/说明

  1. 上面的代码是由公认的“大师”程序员编写的。那家伙单枪匹马写了nginx。

  2. 我没有问过哪种可能的文字硬编码机制更好。因此,不要跑题。

编辑 2

我最初的例子是相当做作和限制性的。以下代码段显示了嵌入到内部硬编码知识中的字符串文字的用法。第一个片段用于配置解析器,告诉它要为哪个字符串设置哪些枚举值,第二个片段更普遍地用作程序中的字符串。只要编译器使用字符串文字的一份副本,我个人对此感到满意,并且由于元素是静态的,它们不会进入全局符号表。

紧随其后的是:

对于那些留在主题上的人,太棒了!

0 投票
3 回答
1923 浏览

assembly - 清除 PF(奇偶校验标志)的一条指令——在结果寄存器中获取奇数位

在 x86 汇编中,是否可以在一条且仅一条指令中清除奇偶校验标志,在任何初始寄存器配置下工作?

这等效于使用任何设置标志的操作(明确排除)创建具有奇数mov位的结果寄存器。

相比之下,设置奇偶校验标志可以在一条指令中完成:

并且有很多方法可以用两条指令清除奇偶校验标志:

然而,单一指令的方法仍然难以捉摸。

0 投票
2 回答
892 浏览

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?

0 投票
6 回答
273 浏览

c# - 如何测试哪种方法实现运行得更快

虽然检查输入是否为字符串类型的问题已关闭,但其中两个答案在我脑海中引发了一个微优化问题:以下两种解决方案中哪一种表现更好?

Reed Copsey提供了一个解决方案,使用Char.IsLetter

使用来自Mark Byers的正则表达式改编的解决方案:

不想只问 Reed 或 Mark 的问题,我想我会写一个快速测试来确定哪个表现更好。问题是我没有做很多代码优化(我倾向于把代码可读性放在首位)。

除了在每个运行之前和之后获取时间戳之外,还有哪些其他(更好的?)选项可以确定哪个解决方案运行得更快?

编辑

我修改了Martin 的答案以使用Console.WriteLine(...)并将其作为控制台应用程序运行。不确定LinqPad如何运行应用程序,但结果大致相同:

0 投票
7 回答
1252 浏览

c - 使用两个循环体还是一个(结果相同)?

我一直想知道在更好地利用 CPU 缓存方面什么更有效(众所周知,这会受益于引用的局部性)——两个循环,每个循环都迭代相同的数学数字集,每个循环都有不同的主体语句(例如为集合的每个元素调用一个函数),或者有一个循环,其主体相当于两个(或多个)主体语句。在所有循环之后,我们假设相同的应用程序状态。

在我看来,有两个循环会引入更少的缓存未命中和驱逐,因为循环使用的更多指令和数据适合缓存。我对吗?

假设:

  1. 与循环的成本相比f,调用的成本可以忽略不计g

  2. fg单独使用大部分缓存,因此当一个又一个被调用时缓存会溢出(单循环版本的情况)

  3. 英特尔酷睿双核 CPU

  4. C语言源代码

  5. GCC 编译器,“没有额外的开关”

如果可能的话,我想要“过早的优化是邪恶的”角色之外的答案。

我提倡的双循环版本的一个示例:

0 投票
7 回答
181 浏览

java - 这两个 Java 段的性能有什么不同吗?

我很想知道这两个 Java 方法调用中的任何一个在处理器时间、内存分配和/或垃圾收集方面的行为是否完全不同。

对比

0 投票
8 回答
428 浏览

c++ - 关于循环速度的问题

我有以下两个循环:

我跑了三遍。在前两次运行中,第二次循环最快,但在第三次运行中,第一次循环最快。这是什么意思?哪个更好?这取决于情况吗?

0 投票
3 回答
176 浏览

c# - 优化查找

我有一个用于查找值的数组。我使用前 2 个值来获取 n 行。例如,所有行在第一列有 2,在第二列有 7。 获得这些值的最快(我的意思是微优化)方法是什么? 我现在使用 for 循环来获取值:

编辑: 它只有大约 60 行。如果我创建 3 个嵌套数组,那么我可以像 t[2][7] 一样直接使用前 2 列作为索引,然后我只会遍历我真正需要的行。那会更快吗?

桌子:

0 投票
2 回答
57 浏览

sql - 创建为 FULLTEXT 搜索优化的第二列有什么意义吗?

我正在处理的项目对于需要搜索的每一列都有一个名为“ft[columnname]”的第二列,它有一个 FULLTEXT 索引,并且只搜索这一列。

此列包含一个“优化”文本,它是通过以下方式从原始列自动生成的:

  • 字符串是小写的
  • 删除所有重音
  • 删除所有标点符号和无法搜索的字符
  • 所有重复的单词都被删除
  • 所有单词从最长到最短排序
  • 我不太了解的其他转换(与组合词有关)

例如“我喜欢神奇宝贝,尤其是皮卡丘!” 变成“特别是像我这样的口袋妖怪皮卡丘”。

是否有任何(甚至是非常小的)性能优势?数据库中的数据永远不会动态变化。

0 投票
2 回答
309 浏览

c - 微优化:将 intptr_t 用于标志/布尔类型

据我了解, intptr_t 的定义因架构而异——它保证能够表示一个指针,该指针可以访问进程的所有统一地址空间。

Nginx(流行的开源网络服务器)定义了一个用作标志(布尔值)的类型,这是一个 typedef 到intptr_t. 现在以 x86-64 架构为例——它可以访问涵盖所有大小操作数的大量指令——为什么将标志定义为 intptr_t ?当然,使用 32 位 bool 类型的传统也符合要求吗?

我已经了解了 32 位 Vs。当我还是一名新开发人员时,我自己争论 8 位布尔值,结论是由于处理器设计的复杂性,32 位布尔值在常见情况下表现更好。那么为什么需要转移到 64 位 bools 呢?