返回顶部
首页 > 资讯 > 后端开发 > GO >go和c++的map性能对比
  • 336
分享到

go和c++的map性能对比

2024-04-04 23:04:15 336人浏览 独家记忆
摘要

golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《Go和c++的map性能对比》带大家来了解一下##content_title##,希望

golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《Goc++的map性能对比》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发


问题内容

我不明白为什么 golang 在这个操作上比 c++ 快了 10 倍,甚至 go 中的映射查找比 c++ 快了 3 倍。

这是 c++ 代码片段

#include <iOStream>
#include <unordered_map>
#include <chrono>

std::chrono::nanoseconds elapsed(std::chrono::steady_clock::time_point start) {
    std::chrono::steady_clock::time_point now = std::chrono::high_resolution_clock::now();
    return std::chrono::duration_cast<std::chrono::nanoseconds>(now - start);
}
void make_map(int times) {
    std::unordered_map<double, double> hm;
    double c = 0.0;
    for (int i = 0; i < times; i++) {
        hm[c] = c + 10.0;
        c += 1.0;
    }
}

int main() {
    std::chrono::steady_clock::time_point start_time = std::chrono::high_resolution_clock::now();
    make_map(10000000);
    printf("elapsed %lld", elapsed(start_time).count());
}

这是 golang 代码片段:

func makeMap() {
    o := make(map[float64]float64)
    var i float64 = 0
    x := time.Now()
    for ; i <= 10000000; i++ {
        o[i] = i+ 10
    }
    TimeTrack(x)
}
func TimeTrack(start time.Time) {
    elapsed := time.Since(start)

    // Skip this function, and fetch the PC and file for its parent.
    pc, _, _, _ := runtime.Caller(1)

    // Retrieve a function object this functions parent.
    funcObj := runtime.FuncForpc(pc)

    // Regex to extract just the function name (and not the module path).
    runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
    name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")

    log.Println(fmt.Sprintf("%s took %s", name, elapsed))
}

我想知道的是如何优化c++以获得更好的性能。


解决方案


已更新以测量 cppgo 的类似操作。它在调用制图函数之前开始测量,并在函数返回时结束测量。两个版本都在地图中保留空间并返回创建的地图(从中打印几个数字)。

稍微修改了cpp

#include <iostream>
#include <unordered_map>
#include <chrono>

std::unordered_map<double, double> make_map(double times) {
    std::unordered_map<double, double> m(times);

    for (double c = 0; c < times; ++c) {
        m[c] = c + 10.0;
    }
    return m;
}

int main() {
    std::chrono::high_resolution_clock::time_point start_time = std::chrono::high_resolution_clock::now();
    auto m = make_map(10000000);
    std::chrono::high_resolution_clock::time_point end_time = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time-start_time);
    std::cout << elapsed.count()/1000000000. << "s\n";
    std::cout << m[10] << "\n"
              << m[9999999] << "\n";    
}

% g++ -dndebug -std=c++17 -ofast -o perf perf.cpp
% ./perf
2.81886s
20
1e+07

稍微修改了go版本:

package main

import (
    "fmt"
    "time"
)

func make_map(elem float64) map[float64]float64 {
    m := make(map[float64]float64, int(elem))
    var i float64 = 0
    for ; i < elem; i++ {
        m[i] = i + 10
    }
    return m
}

func main() {
    start_time := time.now()
    r := make_map(10000000)
    end_time := time.now()
    fmt.println(end_time.sub(start_time))
    fmt.println(r[10])
    fmt.println(r[9999999])
}

% go build -a perf.go
% ./perf
1.967707381s
20
1.0000009e+07

它看起来不像更新之前那样是平局。拖慢 cpp 版本速度的一件事是 double 的默认哈希函数。当用一个非常糟糕(但很快)的哈希器替换它时,我的时间减少到了 1.89489 秒。

struct bad_hasher {
    size_t operator()(const double& d) const {
        static_assert(sizeof(double)==sizeof(size_t));

        return
            *reinterpret_cast<const size_t*>( reinterpret_cast<const std::byte*>(&d) );
    }
};

确定“c++ 的速度”(几乎对于任何特定事物)有点困难,因为它可能取决于很多变量,例如您使用的编译器。例如,对于此代码的 c++ 版本,我通常会发现 GCc 和 msvc 之间存在 2:1 左右的差异。

就 c++ 和 go 之间的差异而言,我猜这主要是由于哈希表实现方式的差异。一个明显的一点是,go 的 map 实现一次以 8 个元素为一个块来分配数据空间。至少在我见过的标准库实现中,std::unordered_map 每个块仅放置一项。

我们预计这意味着在典型情况下,c++ 代码将从堆/空闲存储中执行更多数量的单独分配,因此其速度将在很大程度上取决于堆管理器的速度。 go 版本还应该具有更高的引用局部性,以便更好地利用缓存

考虑到这些差异,我对您只看到 10:1 的差异感到有点惊讶。我的直接猜测会(稍微)高于这个数字,但众所周知,一次测量值胜过 100 次猜测。

参考

Go's Map Implementation

liststdc++ unordered_map

libc++ unordered_map

理论要掌握,实操不能落!以上关于《go和c++的map性能对比》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注编程网公众号吧!

您可能感兴趣的文档:

--结束END--

本文标题: go和c++的map性能对比

本文链接: https://lsjlt.com/news/596198.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • go和c++的map性能对比
    Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《go和c++的map性能对比》带大家来了解一下##content_title##,希望...
    99+
    2024-04-04
  • Go语言和Java的区别:性能对比
    性能对比:Go语言和Java 概述 Go语言和Java都是流行的编程语言,但它们在性能方面存在一些差异。Go语言因其出色的并发性和低延迟而闻名,而Java则因其稳定性和跨平台性而受到欢迎。在本文中,我们将比较...
    99+
    2024-02-01
    java 区别 go语言
  • 性能对比:Go语言与C语言的速度和效率
    性能对比:Go语言与C语言的速度和效率 在计算机编程领域,性能一直是开发者们关注的重要指标。在选择编程语言时,开发者通常会关注其速度和效率。Go语言和C语言作为两种流行的编程语言,被广...
    99+
    2024-03-10
    性能分析 编程效率 go vs c go语言 底层开发 标准库
  • Go库bytes.Buffer和strings.Builder使用及性能对比
    目录前言bytes.Buffer 和 strings.Builder用法区别性能对比前言 字符串拼接是老生常谈了。在 Go 语言中,常见的拼接字符串的方法有:用+号,或者使用fmt...
    99+
    2022-12-15
    Go bytes.Buffer对比strings.Builder bytes.Buffer strings.Builder性能对比
  • Hadoop和spark的性能对比
    本篇内容主要讲解“Hadoop和spark的性能对比”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hadoop和spark的性能对比”吧!Hadoop和spark的性能有何区别。  如果说Had...
    99+
    2023-06-02
  • TIDB和MySQL性能对比
            最近对比TiDB和MySQL在大表复杂join方面,TiDB比MySQL快很多(至少三倍),这应该得益于TiD...
    99+
    2024-04-02
  • Go和Python Web服务器性能对比分析
    本篇内容介绍了“Go和Python Web服务器性能对比分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • Node、PHP、Java和Go服务端I/O性能对比
    本篇内容主要讲解“Node、PHP、Java和Go服务端I/O性能对比”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node、PHP、Java和Go服务端I/O性能对比”吧!了解应用程序的输入/...
    99+
    2023-06-20
  • 怎样对比mysqlpump和mysqldump的性能
    本篇文章给大家分享的是有关怎样对比mysqlpump和mysqldump的性能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 ...
    99+
    2024-04-02
  • java中Memcached和Redis的性能对比
    这篇文章将为大家详细讲解有关java中Memcached和Redis的性能对比,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面...
    99+
    2023-06-14
  • Laravel 和 CodeIgniter 的性能对比如何?
    laravel 和 codeigniter 框架在性能上非常接近,差异很小,可能因应用程序用例而异。基准测试表明,codeigniter 在数据库查询方面略优,而 laravel 在某些...
    99+
    2024-05-12
    laravel
  • 优化Go语言map的性能
    优化Go语言map的性能 在Go语言中,map是一种非常常用的数据结构,用来存储键值对的集合。然而,在处理大量数据时,map的性能可能受到影响。为了提高map的性能,我们可以采取一些优...
    99+
    2024-04-02
  • c++矩阵计算性能对比:Eigen和GPU解读
    目录生成随机矩阵计算矩阵点积使用显式循环计算使用Eigen库使用GPU结果分析总结生成随机矩阵 生成随机矩阵有多种方式,直接了当的方式是使用显式循环的方式为矩阵的每个元素赋随机值。 ...
    99+
    2022-12-15
    c++矩阵 c++矩阵计算性能对比 c++ Eigen c++ GPU
  • PHP5和PHP8的性能和安全性:对比和改进
    PHP是一种广泛应用的服务器端脚本语言,用于开发Web应用程序。它已经发展了多个版本,而本文将主要讨论PHP5和PHP8之间的比较,特别关注其在性能和安全性方面的改进。 首先让我们来看看PHP5的一些特点。PHP5是在2004年...
    99+
    2024-01-26
    安全性 改进
  • Go语言 vs Java:性能、并发和生态系统的对比
    go和java在性能、并发和生态系统上存在差异。go以goroutine实现高效并发,在吞吐量密集型应用程序中优于java。java拥有庞大的生态系统,而go的生态系统正在快速发展。实战...
    99+
    2024-04-08
    java go语言 apache
  • NumPy和JavaScript在Java中的性能对比?
    在编程领域,性能一直是一个非常重要的话题。对于数据密集型的应用程序而言,选择适当的工具和技术可以大大提高程序的性能。在这篇文章中,我们将重点比较NumPy和JavaScript在Java中的性能,并为您提供一些示例代码来帮助您更好地理解这...
    99+
    2023-10-18
    load javascript numpy
  • C#和Java的对比
    这篇文章主要介绍“C#和Java的对比”,在日常操作中,相信很多人在C#和Java的对比问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#和Java的对比”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!C#...
    99+
    2023-06-18
  • PHP与Go语言对比:性能差异大
    PHP与Go语言是两种常用的编程语言,它们有着不同的特点和优势。其中,性能差异是大家普遍关注的一个问题。本文将从性能角度对比PHP和Go语言,并通过具体的代码示例来展示它们的性能差异。...
    99+
    2024-04-02
  • C++ 生态系统中流行库和框架的性能对比
    c++++ 生态系统中,库和框架的性能表现各异:boost 在向量和字符串处理中卓著。eigen 在矩阵操作中效率最高。fmt 提供最快的字符串格式化。protobuf 在二进制序列化中...
    99+
    2024-05-14
    c++ 生态系统 性能对比
  • 比较Flask应用部署的Gunicorn和uWSGI性能对比
    Flask应用部署:Gunicorn vs uWSGI的比较 引言:Flask作为一种轻量级的Python Web框架,受到了很多开发者的喜爱。在将Flask应用部署到生产环境时,选择适合的服务器网关接口(Server Gate...
    99+
    2024-01-17
    Flask gunicorn uwsgi
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作