首页 > 后端开发 > Golang > 竞争和并行性:Golang 在这方面比 Java 表现更好吗?

竞争和并行性:Golang 在这方面比 Java 表现更好吗?

Linda Hamilton
发布: 2025-01-05 07:30:39
原创
992 人浏览过

Concorrência e paralelismo: o Golang performa melhor que o Java nesse quesito?

Google 创建的语言 Golang(或 Go)的主要优点之一是竞争管理,即能够同时运行多个任务。

每种现代语言都有处理并发的工具。 Go 的与众不同之处在于,运行时为我们抽象了有关线程和并行性的大部分细节,这使得处理变得更加简单。定义如何将 goroutine 分配给操作系统线程以及线程如何与可用 CPU 内核交互的是运行时,而不是操作系统内核。

开发人员可以在Go中同时使用并发(交错执行)和并行(同时执行),甚至可以通过确定程序中同时线程的限制GOMAXPROCS属性来显式地这样做。所以Go可以将goroutine映射到多个核上以获得真正的并行性,并且具有这种架构的机器正在处理。然而,默认情况下,运行时已经为我们进行了这种抽象。

import (
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo
}

登录后复制
登录后复制
登录后复制

其他编程语言也提供并发和并行性工具,但抽象程度和简单性差异很大。例如,在 Java 中,我们有 Concurrent API (java.util.concurrent) 和 Thread、ExecutorService 和 ForkJoinPool 等工具来管理并发和并行性。

但是,开发者需要手动配置线程池或者使用CompletableFuture等特定工具来简化异步操作。

Java 还允许使用线程池在多核机器上并行执行。然而相比之下,Java 中的线程更重,因为它们直接映射到操作系统线程。

运行时 X 内核

操作系统线程由系统内核管理。这意味着创建、销毁、上下文切换和管理线程是内核执行的任务,从而引入了额外的开销。每个操作系统线程都会消耗大量内存(在 Java 中通常约为 1 MB)。当系统在线程之间切换时,需要保存和恢复处理器状态(寄存器、堆栈等),这是一个昂贵的过程。

在 Go 中,是语言运行时执行此管理。 Go 不会为每个 goroutine 创建操作系统线程。相反,Go 运行时在数量少得多的操作系统线程上管理多个 goroutine - 技术上称为 M:N 调度(N 个线程上的 M 个 goroutine)。这允许
数千个具有相同线程数的 goroutine,而不会使操作系统过载。

这就是该语言的“恩典”,使其成为管理高性能分布式系统和实时数据处理应用程序的最爱。

但是,需要强调的是,任何现代语言都能够处理并发和并行性。

区别在于亮度和加工成本。

这样,我们就不需要停留在 FlaxFlu 语言中。每种语言都有其魔力、优点和缺点。

为了展示任何语言如何执行这些任务,我将在 Go 和 Java 中举例说明同一程序是如何编码的,每个程序都有自己的特殊性。这个想法很简单:模拟以并发和并行执行的任务,并打印两种情况下的执行时间和内存使用情况(每个机器的数字各不相同)。

为了让比较更加“豁免”,我让chatgpt生成代码,如下:

戈兰

import (
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo
}

登录后复制
登录后复制
登录后复制

执行时间:141.886206ms
使用内存:43909120 字节

爪哇

package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func tarefa(id int) {
    // Simula algum processamento leve
    time.Sleep(10 * time.Millisecond)
}

func main() {
    // Configura a quantidade de tarefas
    numTarefas := 100000

    // Medindo o tempo de execução
    start := time.Now()

    var wg sync.WaitGroup
    wg.Add(numTarefas)

    // Calculando a quantidade de memória usada
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    initialMemory := m.Sys

    // Criando as goroutines para simular o trabalho
    for i := 0; i < numTarefas; i++ {
        go func(id int) {
            defer wg.Done()
            tarefa(id)
        }(i)
    }

    wg.Wait() // Espera todas as goroutines terminarem

    // Calculando o tempo total de execução e a memória usada
    elapsed := time.Since(start)
    runtime.ReadMemStats(&m)
    finalMemory := m.Sys

    // Printando os resultados
    fmt.Printf("Tempo de execução: %s\n", elapsed)
    fmt.Printf("Memória utilizada: %d bytes\n", finalMemory-initialMemory)
}

登录后复制

执行时间:10238 ms
使用内存:106732888 字节

无论如何,我们可以清楚地用两种语言执行完全相同的任务。每个人都将他们的库用于适当的目的。值得注意的是,Go 的执行速度提高了 98.61%,内存使用量减少了 58.86%。

但是没有比另一种语言更好的了。

我们只需要了解每种语言的优缺点,然后选择哪种语言可以帮助我们解决项目中遇到的问题。每个项目都有其需要解决的特定和独特的问题。

Java 优化

当然,可以使用策略来尝试提高上面提供的 Java 代码的性能。

我再次要求chatgpt将一些技巧融入到初始代码中:

import (
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo
}

登录后复制
登录后复制
登录后复制

为了减少内存消耗,我们使用了 ForkJoinPool,具有更多的线程数(100)以更好地处理高并发。这取代了默认的线程池,确保更多任务可以同时运行。我们还调用了submit和join来确保在结束程序之前所有任务都完成。

通过这些更改,内存分配减少了 56.21%:

执行时间:11877 ms
使用内存:46733064 字节

优化这段代码是一个有趣的挑战。我们邀请您使用 Java 做得更好,这总是有可能的,因为我们知道,无论任何细节,这种语言都很棒。

以上是竞争和并行性:Golang 在这方面比 Java 表现更好吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板