java吧 关注:1,294,324贴子:12,826,867

实践分析下一个编程届的论证

只看楼主收藏回复

很多有特别追求性能上的一直执着 特别是在语言的区别
exp:
C系跑的快 ,Java 跑的慢。
所以我们追求一些底层业务业务性能时应该以理论上的最优C系为实现。例如网络通讯呀,而放弃些面向对象的设计。
今天无聊使用C实现了一个HashMap 和使用Java 的hashMap 实践分析了下。
注意了C的实现是我自己实现的 而hashMap Doug Lea大佬写的。
长话短说,核心代码在rehash 上的区别
C

在重散列过程中,无条件地移动每个元素到新的桶(通过计算得出的新索引)确实会造成一定的开销,尤其是当哈希表的大小变得非常大时。每次重散列,你都需要遍历整个哈希表中的所有元素,并计算它们在新哈希表中的位置,然后将它们插入到新位置。即使使用头插法可以相对快速地将元素插入到新的链表中,这个遍历和重新计算索引的过程本身就是一个完整的线性操作,其时间复杂度为 O(n),其中 n 是元素的数量
******** 所以这里是只用到了链表的头插法 这个的头插法最大的问题是 如果目标是否要移动 它都会被移动 ,就是
[1] x -> x1 -> x2 。假如 x1其实不需要移动 头插法还是会把 x1 插入到x 前面
Java

而JAVA是尾推 + 整体链表移动
我们不考虑JAVA 的红黑带来的性能优势。
在100万的基数上
C
是0.18
JAVA
是 0.145
更优 虽然JAVA 有红黑 + 更好的 hash 算法 但实践证明 相比与语言 算法和结构的选择 会大于语言所带来的性能优势。


IP属地:湖北1楼2024-04-02 12:27回复
    如果一个业务 它不要求语言 但它有一定的性能要求 和 结构化要求 那么有3个选择 C++ , Java ,Go。
    C++性能优秀 。Go 性能好 ,Java 性能及格 。但 C++ 缺少GC和高度的结构化 。Java支持高度的结构化和GC 。go支持结构化和过程化 也有GC 。这就是选择了。


    IP属地:湖北2楼2024-04-02 12:51
    收起回复
      2026-01-12 10:17:46
      广告
      不感兴趣
      开通SVIP免广告
      我们可以把C的算法进一步优化下
      原来的头插法
      [1] x -> x1 -> x2 -> x3 -> x4 。 [9] null
      假如 x2需要移动到[9]
      原来的C的算法是 遍历 [1] 对每个元素都做头插 例如 x不需要一定 那么x 还是会被move 进行头插到[1]

      现在的改进是 x 不动 指针进行向下 到x2时 删除x2 进行头插到[9]
      性能是有优化的
      Max bucket size: 1
      Inserted 1000000 items in 0.159601 seconds
      优化到0.15了 和Java的hash很接近了


      IP属地:湖北3楼2024-04-02 16:42
      回复
        怎么没人呀


        IP属地:湖北4楼2024-04-02 16:57
        回复
          牛啊


          IP属地:北京来自iPhone客户端5楼2024-04-02 17:48
          回复
            又是大佬你


            IP属地:山东来自Android客户端6楼2024-04-02 18:43
            收起回复
              真tm🦅,给你关注一下


              IP属地:陕西来自iPhone客户端7楼2024-04-02 19:31
              回复
                好,给你顶一个,虽然我不太想看懂,但是收获了知识点。Java的性能未必就比c差,主要还得看算法


                IP属地:江西来自Android客户端8楼2024-04-02 21:06
                收起回复
                  2026-01-12 10:11:46
                  广告
                  不感兴趣
                  开通SVIP免广告
                  想看看和go的比较,go的map比较有意思的一点是,它把一个长度为8的哈希桶看做拉链法的一个链表节点,这样应该会比常规一个kv一个节点更加高效


                  IP属地:广东来自iPhone客户端9楼2024-04-02 21:08
                  收起回复
                    老哥关注的挺深入,赞一个


                    IP属地:上海来自Android客户端11楼2024-04-02 23:49
                    回复
                      C的特殊性在于可以直接搞内存,玩过外挂ce么,他就是直接改游戏内存。
                      另外在搞内存语言中,C是最好懂得高级语言,所以经久不衰。


                      IP属地:江苏来自Android客户端13楼2024-04-03 01:45
                      回复
                        go的性能比java强在哪?省内存没话说


                        IP属地:上海来自Android客户端14楼2024-04-03 08:00
                        收起回复
                          太牛看不懂啦


                          IP属地:四川来自Android客户端15楼2024-04-03 08:59
                          回复
                            你初始化一下桶的大小试试,可以减少甚至避免rehash,再比较一下两者之间的性能差远


                            IP属地:四川来自Android客户端16楼2024-04-03 09:25
                            收起回复
                              2026-01-12 10:05:46
                              广告
                              不感兴趣
                              开通SVIP免广告
                              我就一臭写接口的,看不懂思密达


                              IP属地:四川来自Android客户端18楼2024-04-03 12:22
                              回复