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 中的线程更重,因为它们直接映射到操作系统线程。
操作系统线程由系统内核管理。这意味着创建、销毁、上下文切换和管理线程是内核执行的任务,从而引入了额外的开销。每个操作系统线程都会消耗大量内存(在 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 代码的性能。
我再次要求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中文网其他相关文章!