首頁 > 後端開發 > 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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板