为什么 strcmp 比我的函数快得多?

2024-02-19

我写了一个函数,Str::Compare,这基本上是一个strcmp以另一种方式重写。 在比较两个函数时,在循环中重复 500'000'000 次,strcmp执行速度太快,大约x750快几倍。

这段代码是在 C 库中编译的-Os参数有效:

int Str::Compare(char* String_1, char* String_2)
{
    char TempChar_1, TempChar_2;

   do
   {
        TempChar_1 = *String_1++;
        TempChar_2 = *String_2++;
   } while(TempChar_1 && TempChar_1 == TempChar_2);

   return TempChar_1 - TempChar_2;
}

该函数的执行时间是3.058s, while strcmp only 0.004s.

为什么会发生这种情况?

这也是我实现基准循环的方式:

int main()
{
     char Xx[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"},
          Yy[] = {"huehuehuehuehuehuehuehuehuehuehuehuehuehue"};
     for(int i = 0; i < 500000000; ++i)
         Str::Compare(Xx, Yy);
}

Edit: 在测试我编写的一些代码和优化时,效果显着提高Str::Compare速度。 如果之前strcmp was x750现在只快了几倍x250。这是新代码:

int Str::Compare(char* String_1, char* String_2)
{
     char TempChar_1, TempChar_2, TempChar_3;

     while(TempChar_1 && !TempChar_3)
     {
          TempChar_1 = *String_1++;
          TempChar_2 = *String_2++;
          TempChar_3 = TempChar_1 ^ TempChar_2;
     }

     return TempChar_1 - TempChar_2;
}

新的执行时间是0.994s.


我对此很好奇并构建了一个测试程序:

#include <string.h>

compare(char* String_1, char* String_2)
{
    char TempChar_1,
         TempChar_2;

   do
   {
        TempChar_1 = *String_1++;
        TempChar_2 = *String_2++;
   } while(TempChar_1 && TempChar_1 == TempChar_2);

   return TempChar_1 - TempChar_2;
}


int main(){
    int i=strcmp("foo","bar");
    int j=compare("foo","bar");

    return i;
}

我将它编译为汇编程序gcc -S -Os test.c使用 gcc 4.7.3 生成以下汇编程序:

    .file   "test.c"
    .text
    .globl  compare
    .type   compare, @function
compare:
.LFB24:
    .cfi_startproc
    xorl    %edx, %edx
.L2:
    movsbl  (%rdi,%rdx), %eax
    movsbl  (%rsi,%rdx), %ecx
    incq    %rdx
    cmpb    %cl, %al
    jne .L4
    testb   %al, %al
    jne .L2
.L4:
    subl    %ecx, %eax
    ret
    .cfi_endproc
.LFE24:
    .size   compare, .-compare
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "bar"
.LC1:
    .string "foo"
    .section    .text.startup,"ax",@progbits
    .globl  main
    .type   main, @function
main:
.LFB25:
    .cfi_startproc
    movl    $.LC0, %esi
    movl    $.LC1, %edi
    call    compare
    movl    $1, %eax
    ret
    .cfi_endproc
.LFE25:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
    .section    .note.GNU-stack,"",@progbits

我不太擅长 x86 汇编程序,但据我所知,对 strcmp 的调用被删除并简单地替换为常量表达式(movl $1, %eax)。因此,如果您在测试中使用常量表达式,gcc 可能会将 strcmp 优化为常量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 strcmp 比我的函数快得多? 的相关文章

  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 如果.Net Core可以在Windows上运行,为什么不能在.Net Framework中引用.Net Core DLL?

    我明白为什么 Net Framework 可能会在 Net Core IE 中导致问题 因为不存在特定于 Windows 平台的 API 但是为什么不能直接引用 Net Core 作为 Net Framework 中的库呢 如果 Net C
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • std::bind 重载解析

    下面的代码工作正常 include
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • 文件修改时间检查的成本

    对于Linux下包含少量字节的文件 我只需要处理自上次处理以来发生更改的时间 我通过调用 PHP 检查文件是否被更改clearstatcache filemtime 定期 由于整个文件总是很小 因此删除对 filemtime 的调用并通过将

随机推荐

  • 使用 Tensorflow 可以实现增量学习吗?

    我正在尝试使用非常大的数据集 比我的记忆大得多 训练 Tensorflow 模型 为了充分利用所有可用的训练数据 我正在考虑将它们分成几个小 碎片 并一次在一个碎片上进行训练 经过一番研究 我发现这种方法通常被称为 增量学习 并基于这个维基
  • 我应该封装我的 IoC 容器吗?

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我正在尝试确定花费额外的精力来封装 IoC 容器是否有意义 经验告诉我 我应该在我的应用程序和任何第三方组件之间放置一层封装
  • 使用KafkaListener时,如何检查主题消息是否已读完?

    使用 KafkaListener时 如何检查主题消息是否已读完 See 这个答案 https stackoverflow com questions 55430893 how to check if kafka is empty using
  • 使用 * 和 & 比较值是否相等有什么区别?

    我想我在很高的水平上理解两者之间的区别 and Rust 中的内容与内存管理有关 下面的代码片段有什么区别 应用一种方法与另一种方法相比是否存在危险 for i item in bytes iter enumerate if item b
  • Spring JPA Projection 包括链接

    给定一个简单的 Event 模型 它具有一组 Booking 对象 Event Entity public class Event Id GeneratedValue strategy GenerationType AUTO private
  • 将 Google 字体与 Shadow DOM 结合使用 [重复]

    这个问题在这里已经有答案了 我正在尝试在内容脚本端的扩展中使用谷歌字体 我下载并从扩展目录加载的 Noto 字体可以工作 它也在 web accessible resources 中声明 并且在 ShadowDOM 中工作正常 但谷歌字体不
  • Maven 3/Mercury 的良好学习资源

    我一直在尝试了解有关 Maven 3 和 Mercury 的更多信息 Maven Mercury 是 Maven Artifact 子系统的替代品 并且完全替代现有传输的 HTTP HTTPS DAV DAVS 部分 目前似乎可用的实质性内
  • 点阵图条件填充颜色

    Problem 我有一个数据框 我想用lattice的面板点图 不是ggplot2 对其进行可视化 它包含一个变量 应有条件地使用该变量通过不同的颜色填充突出显示数据 可重现的例子 require lattice Make reproduc
  • imp.load_source 方法的第一个参数有什么作用?

    我正在阅读this https stackoverflow com questions 67631 how to import a module given the full path关于从绝对路径导入模块的问题 答案建议使用以下代码 im
  • 如何在 NHibernate 中对两个表进行并集?

    我需要使用 NHibernate 和 HQL 来合并两个表 我在网上找到的帮助很少 我想知道这是否可能 如果可能的话如何 找到了我的答案 http www hibernate org 117 html A21 http www hibern
  • 资源规格和代理跟踪

    我需要解决一个问题 但由于缺乏 Java 培训 我无法解决该问题 要编写什么代码来跟踪获取资源的代理 让我更好地解释一下 我有一系列房间 每个进入该结构的特工都会占用一个房间 并在整个住宿期间保留该房间 我想实时查看哪些房间被占用以及由哪个
  • Int32 的 GetHashCode() 是如何实现的?

    我到处找遍了 但什么也没找到 有人能解释一下吗 根据反射镜 public override int GetHashCode return this 有道理 不是吗
  • 工厂方法 (1) vs 工厂 (2) vs Builder (3) 模式

    用途 1 2 3 的用例是什么 使用它有什么优点和缺点 他们之间有什么区别 工厂方法模式 这种模式与工厂模式非常相似 客户端也从类层次结构中向工厂请求特定类型的对象 但是工厂模式的 Create 方法工厂类将特定对象的创建委托给派生类并返回
  • 如何从管道 (jenkinsfile) 中使用 Jenkins Copy Artifacts 插件?

    我试图找到一个在 Jenkins 管道 工作流程 中使用 Jenkins Copy Artifacts 插件的示例 谁能指出使用它的示例 Groovy 代码吗 通过声明式 Jenkinsfile 您可以使用以下管道 pipeline age
  • 超时已过。操作完成前超时时间已过或服务器未响应

    运行 ssis 包时 我在 ADO net 源中调用 sp 但出现此错误 超时已过 操作完成之前超时时间已过 或者服务器没有响应 我已将命令超时设置为 0 无限时间 但仍然收到错误 sp 在 sql server 中工作正常 大约需要 31
  • Android Studio 签名的 APK 未安装

    我在 Android Studio 中 在 构建 gt 生成签名的 APK 下签署 APK 并使用向导 一切似乎都正常 并生成了一个 apk 文件 当我将此文件复制到我的设备 Nexus 7 或 Moto X 时 它不会安装 我收到 安装失
  • 单击电子邮件链接时出现不受支持的操作错误

    我已在 xml 中提供了指向 TextView 的电子邮件链接 但当我单击 TextView 时 它显示不支持的操作错误 如何将活动链接放在文本视图中的电子邮件上 这是我的 string xml 文件的代码
  • 如何禁用 UIScrollView 的水平滚动?

    我有一个UIView就像iPhone的跳板一样 我已经使用创建它UIScrollView and UIButtons 我想禁用所述滚动视图上的水平滚动 我只想要垂直滚动 我该如何实现这个目标 你必须设置contentSize的财产UIScr
  • Akka/Java getContext().become 带参数?

    在 Akka Scala 中 可以将参数传递给自定义接收函数 因此可以通过 params 传递整个 actor 状态 而无需使用可变变量 context become myCustomReceive param1 param2 但在 Jav
  • 为什么 strcmp 比我的函数快得多?

    我写了一个函数 Str Compare 这基本上是一个strcmp以另一种方式重写 在比较两个函数时 在循环中重复 500 000 000 次 strcmp执行速度太快 大约x750快几倍 这段代码是在 C 库中编译的 Os参数有效 int