All Projects → csimplestring → go-left-right

csimplestring / go-left-right

Licence: other
A faster RWLock primitive in Go, 2-3 times faster than RWMutex. A Go implementation of concurrency control algorithm in paper <Left-Right - A Concurrency Control Technique with Wait-Free Population Oblivious Reads>

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to go-left-right

java-multithread
Códigos feitos para o curso de Multithreading com Java, no canal RinaldoDev do YouTube.
Stars: ✭ 24 (-42.86%)
Mutual labels:  concurrency, concurrent-programming, concurrent-data-structure
Zio
ZIO — A type-safe, composable library for async and concurrent programming in Scala
Stars: ✭ 3,167 (+7440.48%)
Mutual labels:  concurrency, concurrent-programming, concurrent-data-structure
geeteventbus
An inprocess eventbus for highly concurrent Python applications
Stars: ✭ 17 (-59.52%)
Mutual labels:  concurrency, concurrent-programming
Java Concurrency
Java并发知识点总结
Stars: ✭ 3,457 (+8130.95%)
Mutual labels:  concurrency, concurrent-programming
Java Concurrency Progamming Tutorial
BAT华为大厂一线工程师四年磨一剑精心编排 Java 高并发编程案例代码 & 教程 & 面试题集锦。详细文档讲解请阅读本人的知识库仓:https://github.com/Wasabi1234/Java-Interview-Tutorial
Stars: ✭ 606 (+1342.86%)
Mutual labels:  concurrency, concurrent-programming
transit
Massively real-time city transit streaming application
Stars: ✭ 20 (-52.38%)
Mutual labels:  concurrency, concurrent-programming
mux-stream
(De)multiplex asynchronous streams
Stars: ✭ 34 (-19.05%)
Mutual labels:  concurrency, concurrent-programming
Concurrencpp
Modern concurrency for C++. Tasks, executors, timers and C++20 coroutines to rule them all
Stars: ✭ 340 (+709.52%)
Mutual labels:  concurrency, concurrent-programming
scalable-concurrent-containers
High performance containers and utilities for concurrent and asynchronous programming
Stars: ✭ 101 (+140.48%)
Mutual labels:  concurrency, concurrent-programming
Awesome Lockfree
A collection of resources on wait-free and lock-free programming
Stars: ✭ 1,046 (+2390.48%)
Mutual labels:  concurrency, concurrent-programming
Mt
tlock, RWMUTEX, Collab, USM, RSem and other C++ templates for Windows to provide read/write mutex locks, various multithreading tools, collaboration, differential updates and more
Stars: ✭ 18 (-57.14%)
Mutual labels:  concurrency, concurrent-programming
Chymyst Core
Declarative concurrency in Scala - The implementation of the chemical machine
Stars: ✭ 142 (+238.1%)
Mutual labels:  concurrency, concurrent-programming
traffic
Massively real-time traffic streaming application
Stars: ✭ 25 (-40.48%)
Mutual labels:  concurrency, concurrent-programming
TAOMP
《多处理器编程的艺术》一书中的示例代码实现,带有注释与单元测试
Stars: ✭ 39 (-7.14%)
Mutual labels:  concurrency, concurrent-programming
concurrent-resource
A header-only C++ library that allows easily creating thread-safe, concurrency friendly resources.
Stars: ✭ 17 (-59.52%)
Mutual labels:  concurrency, concurrent-data-structure
Golang Tutorials
Go Tutorials - Let's get our hands really dirty by writing a lot of Golang code
Stars: ✭ 277 (+559.52%)
Mutual labels:  concurrency, concurrent-programming
practice
Java并发编程与高并发解决方案:http://coding.imooc.com/class/195.html Java开发企业级权限管理系统:http://coding.imooc.com/class/149.html
Stars: ✭ 39 (-7.14%)
Mutual labels:  concurrency, concurrent-programming
Sobjectizer
An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.
Stars: ✭ 172 (+309.52%)
Mutual labels:  concurrency, concurrent-programming
Fucking Java Concurrency
🎏 Simple show cases of java concurrency problems, seeing 🙈 is believing 🐵
Stars: ✭ 779 (+1754.76%)
Mutual labels:  concurrency, concurrent-programming
Tascalate Concurrent
Implementation of blocking (IO-Bound) cancellable java.util.concurrent.CompletionStage and related extensions to java.util.concurrent.ExecutorService-s
Stars: ✭ 144 (+242.86%)
Mutual labels:  concurrency, concurrent-programming

Go Left Right Concurrency

A Go implementation of the left-right concurrency control algorithm in paper <Left-Right - A Concurrency Control Technique with Wait-Free Population Oblivious Reads>

This library provides a concurrency primitive for high concurrency reads over a single-writer data structure. The micro benchmark shows the left-right pattern is 2-3x faster than the RWMutex.

Why

In Go, RWMutex is your best choice in most cases when handling concurrent read/write situation. However, in some special extreme cases: you do not want the high-concurrent reads to be blocked by infrequent writes.

In this library, an example left-right-pattern map was implemented to compare with the classic RWMutex-based map.

You can apply the same technique on slice, list, stack etc, to make them concurrent-safe if it meets your case: high concurrency reads over a single-writer.

// Only writes: RWMutex-Map is 2x faster than LR-Map 
BenchmarkLRMap_Write                  	12231741	        93.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkLRMap_Write-2                	12355836	        93.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkLRMap_Write-4                	12448788	        92.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkLockMap_Write                	20728842	        54.1 ns/op	       0 B/op	       0 allocs/op
BenchmarkLockMap_Write-2              	20953489	        54.0 ns/op	       0 B/op	       0 allocs/op
BenchmarkLockMap_Write-4              	20412688	        54.0 ns/op	       0 B/op	       0 allocs/op

// Only reads: RWMutex-Map is slightly faster than LR-Map
BenchmarkLRMap_Read                   	 4505625	       224 ns/op	      39 B/op	       0 allocs/op
BenchmarkLRMap_Read-2                 	 5114546	       212 ns/op	      34 B/op	       0 allocs/op
BenchmarkLRMap_Read-4                 	 5271961	       212 ns/op	      33 B/op	       0 allocs/op
BenchmarkLockMap_Read                 	 7331290	       158 ns/op	      11 B/op	       0 allocs/op
BenchmarkLockMap_Read-2               	 6270297	       162 ns/op	      14 B/op	       0 allocs/op
BenchmarkLockMap_Read-4               	 6244382	       162 ns/op	      14 B/op	       0 allocs/op

// 5 readers vs 1 writer: on 2.4 CPUs, LR-map is 2-3x faster than RWMutex-map
BenchmarkLRMap_Read_Write_5_1         	    5794	    205062 ns/op	      46 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_5_1-2       	    3088	    405067 ns/op	      72 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_5_1-4       	    3014	    415573 ns/op	      81 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_5_1       	    7491	    160224 ns/op	      27 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_5_1-2     	    1210	   1031627 ns/op	      94 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_5_1-4     	    1106	   1067645 ns/op	     101 B/op	       1 allocs/op


// 10 readers vs 1 writer: on 2.4 CPUs, LR-map is 2-3x faster than RWMutex-map
BenchmarkLRMap_Read_Write_10_1        	    3236	    354466 ns/op	      70 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_10_1-2      	    1609	    772303 ns/op	     123 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_10_1-4      	    1593	    726723 ns/op	     132 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_10_1      	    4263	    271487 ns/op	      36 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_10_1-2    	     676	   1726200 ns/op	     154 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_10_1-4    	     604	   2007962 ns/op	     172 B/op	       1 allocs/op

// 50 readers vs 1 writer: on 2.4 CPUs, LR-map is 2x faster than RWMutex-map
BenchmarkLRMap_Read_Write_50_1        	     586	   1733163 ns/op	     310 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_50_1-2      	     340	   3532511 ns/op	     527 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_50_1-4      	     367	   3192197 ns/op	     493 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_50_1      	    1004	   1177003 ns/op	     101 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_50_1-2    	     223	   5803691 ns/op	     433 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_50_1-4    	     195	   5741745 ns/op	     466 B/op	       1 allocs/op

// 100 readers vs 1 writer: on 2.4 CPUs, LR-map is 2x faster than RWMutex-map
BenchmarkLRMap_Read_Write_100_1       	     384	   3126528 ns/op	     471 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_100_1-2     	     182	   6503080 ns/op	     974 B/op	       1 allocs/op
BenchmarkLRMap_Read_Write_100_1-4     	     182	   6345014 ns/op	     969 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_100_1     	     500	   2351661 ns/op	     188 B/op	       1 allocs/op
BenchmarkLockMap_Read_Write_100_1-2   	     100	  10701998 ns/op	     973 B/op	       2 allocs/op
BenchmarkLockMap_Read_Write_100_1-4   	     124	  10646446 ns/op	     776 B/op	       1 allocs/op

What

  • Left-Right is a technique with some similarities with Double Instance Locking because it uses two instances, and has a mutex to serialize mutations. In this sense, it is reminiscent of the “Double Buffering” technique used in computer graphics.
  • Left-Right is a generic, linearizable, technique that can provide mutual exclusivity for any object in memory or data structure
  • Left-Right is non-blocking for read-only operations, and fast
  • it is Wait-Free Population Oblivious

See all the details: link

How

After go 1.18

go get github.com/csimplestring/[email protected]

Before go 1.18

go get github.com/csimplestring/[email protected]

Then you can use it to wrap any data structures. See the below example.

import github.com/csimplestring/go-left-right/primitive

type LRMap struct {
	*primitive.LeftRightPrimitive[map[int]int]

    // you have to provides 2 identical instances
	left  map[int]int
	right map[int]int
}

func newIntMap() *LRMap {

	m := &LRMap{
		left:  make(map[int]int),
		right: make(map[int]int),
	}

	m.LeftRightPrimitive = primitive.New[map[int]int]()

	return m
}

func (lr *LRMap) Get(k int) (val int, exist bool) {

    // Go does not have generics, so have to use interface{} for lambda's arguments
	lr.ApplyReadFn(lr.left, lr.right, func(instance map[int]int) {
		val, exist = instance[k]
	})

	return
}

func (lr *LRMap) Put(key, val int) {
	lr.ApplyWriteFn(lr.left, lr.right, func(instance map[int]int) {
		instance[key] = val
	})
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].