C# 指针与 C++ 指针

2024-04-26

我一直在学习编程,并选择 C++ 和 C# 编程作为第一语言。更具体地说,我有一本旧的 C 书,有人好心地借给我,我用它来学习 C#。我使用 Visual Studio Express 并使用 C++ 和 C# 编写。我感兴趣的一个领域是直接内存管理的能力。我正在尝试学习使用它来优化我的代码。然而,我正在努力正确地做到这一点,并且实际上看到了任何真正的性能改进。例如,以下是 C# 代码:

unsafe static void Main(string[] args)
{
    int size = 300000;
    char[] numbers = new char[size];

    for (int i = 0; i < size; i++)
    {
        numbers[i] = '7';
    }

    DateTime start = DateTime.Now;

    fixed (char* c = &numbers[0])
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }

    /*char[] c = numbers;  // commented out C# non-pointer version same 
          speed as C# pointer version
    {
        for (int i = 0; i < 10000000; i++)
        {
            int number = myFunction(c, 100000);
        }
    }*/

    TimeSpan timeSpan = DateTime.Now - start;
    Console.WriteLine(timeSpan.TotalMilliseconds.ToString());
    Console.ReadLine();
}

static int myFunction(ref char[] numbers, int size)
{
    return size * 100;
}

static int myFunction(char[] numbers, int size)
{
    return size * 100;
}

unsafe static int myFunction(char* numbers, int size)
{
    return size * 100;
}

无论我调用三种方法中的哪一种,我都会获得相同的执行速度。我还在尝试理解使用 ref 和使用指针之间的区别,但这可能需要时间和练习。

然而,我不明白的是,我能够在 C++ 中产生非常显着的性能差异。以下是我尝试在 C++ 中近似相同的代码时想到的结果:

/*int myFunction(std::string* numbers, int size)  // C++ pointer version commented 
     out is much faster than C++ non-pointer version
{
    return size * 100;
}*/

int myFunction(std::string numbers, int size) // value version
{
    return size * 100;
}

int _tmain(int argc, _TCHAR* argv[])
{
int size = 100000;
std::string numbers = "";
for (int i = 0; i < size; i++)
{
    numbers += "777";
}

clock_t start = clock();

for (int i = 0; i < 10000; i++)
{
    int number = myFunction(numbers, 100000);
}

clock_t timeSpan = clock() - start;

std::cout << timeSpan;
char c;
std::cin >> c;

return 0;
}

谁能告诉我为什么我的 C# 代码没有从我使用引用或指针中受益?我一直在网上阅读东西等等,但我被困住了。


C# 已经生成了指针,而无需您显式声明它们。每个参考类型参考,例如您的numbers变量,实际上是运行时的指针。你传递的每一个参数ref or out关键字实际上是运行时的指针。在 C++ 中,数组参数的 C 等价物是 char**, char*&。 C# 中没有区别。

因此,您不会看到速度有任何差异,因为实际执行的代码是相同的。

这也不完全是它停止的地方,你实际上从未对数组做任何事情。您调用的方法在运行时消失,就像在 C 或 C++ 编译器中一样,它将inlined由优化器。由于您不使用数组参数,因此您也不会获得任何代码。

当您使用指针来实际寻址内存时,指针对于加快程序速度非常有用。您可以为数组建立索引,并确保您永远不会为数组边界检查付费。在许多情况下,您也不会在正常使用中为此付费,如果抖动优化器知道索引始终是安全的,那么它会相当聪明地删除检查。那是unsafe使用指针,您可以轻松地写入不属于数组的内存部分,并以这种方式破坏 GC 堆。用于对象引用或ref争论从来都不是不安全的。

查看这些内容的唯一真正方法是查看生成的机器代码。调试+Windows+反汇编窗口。重要的是,即使您调试代码或看不到优化,代码仍然可以得到优化。请务必运行发布版本并使用“工具+选项”、“调试”、“常规”,取消选中“抑制模块加载时的 JIT 优化”选项。需要熟悉机器代码才能理解您所看到的内容。

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

C# 指针与 C++ 指针 的相关文章

随机推荐

  • 当我从 Django 应用程序“打印”它们时,它们会去哪里?

    我在 Linux 服务器上有一个 Django 应用程序 在其中一种观点中 某种形式print命令被执行 并打印一些字符串 我怎样才能知道打印的字符串是什么 是否有一些日志保存这些东西 输出应该在 django 启动的终端中 如果你不直接启
  • Cassandra 中的强一致性

    根据datastax文章 可以保证强一致性 如果 R W gt N 在哪里 R是读操作的一致性级别 W为写操作的一致性级别 N 是副本数 这里的强一致性是什么意思呢 这是否意味着 每次 从数据库给出查询响应时 响应将 始终 是最后更新的值
  • 跨 AVX 通道的最佳方式是什么?

    有些问题具有类似的标题 但我的问题涉及其他地方未涵盖的一个非常具体的用例 我有 4 个 128d 寄存器 x0 x1 x2 x3 我想将它们的内容重新组合在 5 个 256d 寄存器 y0 y1 y2 y3 y4 中 以准备其他计算 on
  • 使用 C#/C++ 托管 VST/DX 仪器? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我试图了解用 C 或 C 构建准系统虚拟仪器主机所需的工作量 但我无法获得任何硬信息 有人知道有什么好的
  • Pandas DataFrame MultiIndex groupby 滚动操作缺少日期

    我有一个数据框 其中有一个 MultiIndex 其中索引的最后一列是日期 我正在尝试以特定频率对列进行滚动操作 据我了解 如果我有 TimeIndex 通常的 pandas 方法是使用频率字符串调用滚动函数 例如 如果我希望窗口为两天 则
  • VB6 和 .PFX 代码签名

    我的老板已经从 Comodo 获得了证书 而我一直在努力寻找获得证书问题的解决方案intoVB6 应用程序 证书本身是 VB6 格式的 我对这类事情几乎一无所知 Comodo 的人真是太乐于助人了 我的老板说他可以在互联网上找到一些东西 显
  • 找出用于制作 JAR 的 Scala 版本

    我试图弄清楚使用哪个 Scala 版本进行编译A jar 我有两个版本 一个来自我的 ivy2 存储库 另一个来自 Maven 运行后jar xf A jar 我苦苦寻找scala and version 但什么也没发现 grep ri s
  • Mechanize 出现 SSL 错误

    我得到了这些命令irb require mechanize agent Mechanize new agent get https monabo lemonde fr customer account forgotpassword 我收到这
  • highcharts 弄错了我的时间

    highcharts 弄错了我的时间 我来自委内瑞拉 以防万一 我正在做一个实时系统 我可以在数据库中获取时间 秒和毫秒 例如 10 39 09 2 我应用 strtotime time 然后通过 json 发送到图表 在我的高图表中 我进
  • Seaborn 线图使用中位数而不是均值

    我在用着seaborn lineplot 创建像这样的线图 代表平均值的线 由代表标准差的带包围 sns lineplot x trial y rvalues hue subject err style band ci sd data df
  • 从文件中读取行,在第二个文件中 grep ,并为每个 $line 输出一个文件

    我有以下两个文件 sequences txt 158333741 Acaryochloris marina MBIC11017 uid58167 158333741 432 1 432 COG0001 0 158339504 Acaryoc
  • 如何在 spring-data-mongodb 框架中将 BigDecimal 转换为 Double

    Spring Data MongoDB 映射默认将 BigDecimal 转换为 String 但是 我希望它们在 mongodb 中转换为 Double 这是后者在 mongodb 中对该字段进行查询 比较查询 聚合查询 所必需的 我如何
  • 合并排序代码不起作用并显示异常

    public static void Merge int arr int p int q int r int n1 q p int n2 r q int L new int n1 int R new int r n2 for int i 0
  • 如何访问 Flask 路由中的查询字符串?

    如何访问 Flask 路由中的查询参数或查询字符串 从 Flask 文档来看 这一点并不明显 示例路线 data下面说明了我想要访问该数据的上下文 如果有人要求类似的东西example com data abc 123 我想访问该字符串 a
  • 如何在特定时间后从“std::cin”读取超时

    我写了一个小程序 int main int argc char argv int n std cout lt lt Before reading from cin lt lt std endl Below reading from cin
  • CUDA线程执行顺序

    我有一个 CUDA 程序的以下代码 include
  • 如何实现 Spring XD 接收器?

    到目前为止 我已经实现了 Spring XD 处理器 例如像这样 MessageEndpoint public class MyTransformer Transformer inputChannel input outputChannel
  • Rcpp 调试 - 致命错误:Datetime.h:没有这样的文件或目录; xtsAPI.h:没有这样的文件或目录

    我正在使用 Rcpp 来处理 Datetime 和 xts 数据 但是 我收到错误No such file or directory以下代码的第 2 行和第 3 行均出现错误 include
  • 如何使用 js/uml 对 JavaScript 文件进行逆向工程?

    Goal 我的目标是从我的 JavaScript 项目 由多个 js 文件组成 中获取 UML 模型并将其存储为 XMI 我已经走了多远 我在网上搜索了一下 发现js uml是第一个去的地方 我已经设法让 js uml 插件与 Eclips
  • C# 指针与 C++ 指针

    我一直在学习编程 并选择 C 和 C 编程作为第一语言 更具体地说 我有一本旧的 C 书 有人好心地借给我 我用它来学习 C 我使用 Visual Studio Express 并使用 C 和 C 编写 我感兴趣的一个领域是直接内存管理的能