One of the main advantages of Golang (or Go), a language created by Google, is competition management, that is, the ability to run multiple tasks at the same time.
Every modern language has tools to deal with concurrency. What sets Go apart is that the runtime abstracts most of the details about threads and parallelism for us, which makes this processing much simpler. It is the runtime, not the operating system kernel, that defines how goroutines are assigned to operating system threads and how the threads interact with the available CPU cores.
The developer can use concurrency (interleaved execution) and parallelism (simultaneous execution) at the same time in Go. And he can even do so explicitly by determining the GOMAXPROCS property which is the limit of simultaneous threads in the program. So Go can map goroutines on multiple cores to obtain real parallelism, and machines that have this architecture in processing. By default, however, the runtime already does this abstraction for us.
import ( "runtime" ) func main() { runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo }
Other programming languages also offer tools for concurrency and parallelism, but the level of abstraction and simplicity varies greatly. In Java, for example, we have the Concurrent API (java.util.concurrent) and tools such as Thread, ExecutorService and ForkJoinPool to manage concurrency and parallelism.
However, the developer needs to manually configure the thread pool or use specific tools like CompletableFuture to simplify asynchronous operations.
Java also allows parallel execution on multicore machines using thread pools. In contrast, however, threads in Java are heavier because they are mapped directly to operating system threads.
Operating system threads are managed by the system kernel. This means that creating, destroying, context switching, and managing threads are tasks that the kernel performs, introducing additional overhead. Each operating system thread consumes a significant amount of memory (typically around 1 MB in Java). When the system switches between threads, it needs to save and restore processor states (registers, stack, etc.), which is an expensive process.
In Go, it is the language runtime that does this management. Go does not create an operating system thread for each goroutine. Instead, the Go runtime manages multiple goroutines on a much smaller number of operating system threads - technically called M:N scheduling (M goroutines on N threads). This allows
thousands of goroutines with the same number of threads without overloading the operating system.
And this is the "grace" of the language, making it the favorite for managing high-performance distributed systems and real-time data processing applications.
However, however, it is important to emphasize that any modern language is capable of working with concurrency and parallelism.
The difference is in lightness and processing cost.
This way, we don't need to stay in a FlaxFlu of languages. Each language has its magic, its strengths and weaknesses.
Just to show how any language can perform these tasks, I will exemplify in Go and Java how the same program is coded, each with its own particularities. The idea is simple: simulate a task performed with concurrency and parallelism and print the execution time and memory usage in both cases (the numbers vary for each machine).
To make the comparison more "exempt", I asked chatgpt to generate the codes, which are below:
import ( "runtime" ) func main() { runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo }
Execution time: 141.886206ms
Memory used: 43909120 bytes
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) }
Execution time: 10238 ms
Memory used: 106732888 bytes
Anyway, we can clearly perform exactly the same task in both languages. Each using their libraries for the appropriate purposes. It is noted that in Go the execution was 98.61% faster and 58.86% less memory was used.
But there is no better language than another.
What we just need is to understand the pros and cons of each one when choosing which language can help us solve the problems we have in our projects. And each project will have its pool of particular and unique problems that need to be resolved.
It is possible, of course, to use strategies to try to improve the performance of the code provided above in Java.
I asked chatgpt again to incorporate some tricks up its sleeve into the initial code:
import ( "runtime" ) func main() { runtime.GOMAXPROCS(4) // Permitir até 4 threads para paralelismo }
To reduce memory consumption, we use a ForkJoinPool, with a greater number of threads (100) to better deal with high concurrency. This replaces the default thread pool, ensuring more tasks can run simultaneously. We also call submit and join to ensure that all tasks are completed before ending the program.
With these changes, memory allocation was reduced by 56.21%:
Execution time: 11877 ms
Memory used: 46733064 bytes
Optimizing this code is an interesting challenge. We invite you to do better using Java, which is always very possible, since this language, we know, is wonderful regardless of any detail.
The above is the detailed content of Competition and parallelism: does Golang perform better than Java in this regard?. For more information, please follow other related articles on the PHP Chinese website!