Matt Gallagerã®èšäºã®ç¿»èš³ã
ãã®èšäºã§ã¯ãSwiftã®ã¹ã¬ããåããŒã«ãšã¹ã¬ããåæããŒã«ã®æ¬ åŠã«ã€ããŠèª¬æããŸãã Swiftã«åæå®è¡æ§ãå°å ¥ããããã®ææ¡ãšããã®æ©èœã䜿çšå¯èœã«ãªãåã«ãSwiftã§ã®ã¹ããªãŒãã³ã°å®è¡ã§åŸæ¥ã®ãã¥ãŒããã¯ã¹ãšå ±æå¯å€ç¶æ ã䜿çšããæ¹æ³ã«ã€ããŠèª¬æããŸãã
Swiftã§ãã¥ãŒããã¯ã¹ã䜿çšããããšã¯ç¹ã«å°é£ã§ã¯ãããŸãããããã®èæ¯ã«å¯ŸããŠãSwiftã®ããã©ãŒãã³ã¹ã®åŸ®åŠãªãã¥ã¢ã³ã¹-ã¯ããŒãžã£ã«ãããã£ããã£äžã®åçã¡ã¢ãªå²ãåœãŠã匷調ããããšæããŸãã ãã¥ãŒããã¯ã¹ãé«éã«ãããã®ã§ããããã¥ãŒããã¯ã¹å ã§å®è¡ããã¯ããŒãžã£ãæž¡ããšãã¡ã¢ãªã®ãªãŒããŒããããå¢ãããããããã©ãŒãã³ã¹ã10åäœäžããå¯èœæ§ããããŸãã ãã®åé¡ã解決ããããã€ãã®æ¹æ³ãèŠãŠã¿ãŸãããã
Swiftã®ã¹ã¬ããåã®æ¬ åŠ
Swiftã2014幎6æã«åããŠçºè¡šããããšãã2ã€ã®æãããªæ¬ èœããããŸããã
- ãšã©ãŒåŠç
- ã¹ããªãŒã ã®å®è¡ãšã¹ã¬ããã®åæã
ãšã©ãŒåŠçã¯Swift 2ã§å®è£ ããããã®ãªãªãŒã¹ã®éèŠãªæ©èœã®1ã€ã§ããã
ã¹ããªãŒãã³ã°ã®å®è¡ã¯ãSwiftã«ãã£ãŠãŸã ã»ãšãã©ç¡èŠãããŠããŸãã ã¹ããªãŒã å®è¡çšã®èšèªããŒã«ã®ä»£ããã«ãSwiftã«ã¯ãã¹ãŠã®ãã©ãããã©ãŒã ã«
Dispatch
ã¢ãžã¥ãŒã«ïŒlibdispatchãå¥åGrand Central DispatchïŒãå«ãŸããŠãããèšèªã®ãã«ããæåŸ ãã代ããã«
Dispatch
ã䜿çšããããšãæé»çã«æäŸããŸãã
åºè·ãããã©ã€ãã©ãªãžã®è²¬ä»»ã®å§ä»»ã¯ãã¹ããªãŒã å®è¡ããªããã£ããšå³æ Œãªã¹ã¬ããã»ãŒãïŒããããïŒãèšèªã®äž»ãªç¹æ§ã«ãªã£ãŠããGoãRustãªã©ã®ä»ã®çŸä»£èšèªãšæ¯èŒãããšç¹ã«å¥åŠã«æããŸãã Objective-Cã®
@synchronized
ããã³
atomic
ããããã£ã§ãããSwiftã«ãã®ãããªãã®ããªãããšãšæ¯èŒãããšãå¯å€§ãªãªãã¡ãŒã®ããã«èŠããŸãã
ãã®èšèªã®ãã®ãããªæãããªçç¥ã®çç±ã¯äœã§ããïŒ
Swiftã®å°æ¥ã®ãã«ãã¹ã¬ãã
çãã¯ãSwiftãªããžããªã§ã®ãã«ãã¹ã¬ããã®å®è£ ã®ææ¡ã§ç°¡åã«èª¬æãããŠããŸã ã
ç§ã¯ãã®æã«èšåããŠãSwiftéçºè ãå°æ¥ãã«ãã¹ã¬ããã«ã€ããŠäœãããããããšã匷調ããŸãããSwiftéçºè Joe GroffãèšãããšãèŠããŠãããŠãã ããïŒããã®ææžã¯åãªãææ¡ã§ãããå ¬åŒã®çŽ¹ä»æã§ã¯ãããŸããéçºãã
ãã®ææ¡ã¯ãããšãã°ã CycloneãŸãã¯Rustã§ãã¹ã¬ããéã§ãªã³ã¯ãå ±æã§ããªãç¶æ³ã説æããããã«æãããŸããã çµæããããã®èšèªã«äŒŒãŠãããã©ããã«é¢ä¿ãªããSwiftã¯ã
Copyable
ãå®è£ ããå³å¯ã«å¶åŸ¡ããããã£ãã«ïŒ
Stream
ãšåŒã°ããæã§ïŒãä»ããŠéä¿¡ãããåãé€ããã¹ããªãŒã ã®å ±æã¡ã¢ãªãåé€ããäºå®ã§ãã ïŒ
Task
'sãšåŒã°ããæã§ïŒã³ã«ãŒãã³ã衚瀺ãããŸããããã¯ãéåæãã£ã¹ããããããã¯ãšããŠåäœããäžæåæ¢/åéã§ããŸãã
ããã«ããã®ææ¡ã§ã¯ã
Stream / Task / Copyable
ããªããã£ãã®äžã®ã©ã€ãã©ãªã«ãæãäžè¬çãªèšèªã¹ããªãŒãã³ã°å®è¡
Stream / Task / Copyable
ãå®è£ ã§ãããšè¿°ã¹ãŠããŸãïŒGoã®
chan
ã.NETã®
async / await
ãErlangã®
actor
ã«äŒŒãŠ
async / await
ãŸãïŒã
è¯ãããã«èãããŸãããSwiftã§ãã«ãã¹ã¬ããåãæåŸ ããå Žåã¯ïŒ Swift 4ã§ã¯ïŒ Swift 5ã§ã¯ïŒ ããã«ã
ãããã£ãŠãä»ã§ã¯ããã¯ç§ãã¡ãå©ããŸãããããããç§ãã¡ãæ··ä¹±ãããŸãã
çŸåšã®ã©ã€ãã©ãªã«å¯Ÿããå°æ¥ã®æ©èœã®åœ±é¿
åé¡ã¯ãSwiftãèšèªã§ã®åçŽãªãã«ãã¹ã¬ããããªããã£ãã®äœ¿çšããŸãã¯å°æ¥ã®æ段ã§çœ®ãæãããããåé€ããããšããçç±ã§ãèšèªé¢æ°ã®ã¹ã¬ããã»ãŒãããŒãžã§ã³ã䜿çšããªãããšã§ãã
Swift-Evolutionã¡ãŒãªã³ã°ãªã¹ããèªããšããã®ããšã®æ確ãªèšŒæ ãèŠã€ããããšãã§ããŸãã
- ãªããžã§ã¯ããžã®åç §ïŒåŒ·ããã®ãšåŒ±ããã®ã®äž¡æ¹ïŒã¯ããèªã¿åã/æžã蟌ã¿ãæžã蟌ã¿/æžã蟌ã¿ããŸãã¯äœããååšããå Žå/ã¬ãŒã·ã³ã°å€æ°ã«ããŒã¿ãç Žå£ããããšå®çŸ©ãããŠããŸãã ã ããã§ã¯ããã®è¡åãå€æŽããããçµ±åããããååãã¢ãããŒããææ¡ãããããæå³ã¯ãããŸããããç§ãã¡ãæ¡çšããæ°å°ãªãææ§ãªè¡åã«ãŒã«ã®1ã€ãã ããã§ãã ãã®ãããŸããªåäœã®èãããããä¿®æ£ãã¯ãæ°ãããã«ãã¹ã¬ããã¢ãã«ã§ãã
- çµæã®åïŒãŸãã¯æ©èœçãªã€ã³ã¿ãŒãã§ã€ã¹ä»¥å€ã®ãã®ä»ã®ã¹ããŒæ段ïŒã¯ãå€æ°ã®ç¶ç¶ããã·ã³ã°ã¹ã¿ã€ã«ã¢ã«ãŽãªãºã ã«æçšã§ããã培åºçã«è°è«ãããŸãããæçµçã«ã¯ç¡èŠãããŸããã«ãã¹ã¬ããã®å€æŽã®äžéšãšããŠãSwiftããé©åãªèšèªãµããŒããæäŸãããŸã§ïŒã³ã«ãŒãã³ãŸãã¯éåæã®çŽæïŒãã
é«éãªæ±çšãã¥ãŒããã¯ã¹ãã¥ãŒããã¯ã¹ãèŠã€ããããšããŠããŸã
ã€ãŸãããã«ãã¹ã¬ããã®åäœãå¿ èŠãªå Žåãæ¢åã®ã¹ããªãŒãã³ã°ããŒã«ãšãã¥ãŒããã¯ã¹ããããã£ã䜿çšããŠèªåã§ãã«ãããå¿ èŠããããŸãã
æšæºã®Swiftãã¥ãŒããã¯ã¹ã®ãã³ã ïŒ
DispatchQueue
ã䜿çšããŠããã®äžã§
sync
ãåŒã³åºããŸãã
ç§ã¯libdispatchã奜ãã§ãããã»ãšãã©ã®å Žåã
DispatchQueue.sync
ããã¥ãŒããã¯ã¹ãšããŠäœ¿çšããããšã¯ãåé¡ã解決ããæãé ãæ¹æ³ã§ããã
sync
é¢æ°ã«æž¡ãããã¯ããŒãžã£ãŒã«ãããã£ããã£ã®é¿ããããªãã³ã¹ãã®ãããä»ã®ãœãªã¥ãŒã·ã§ã³ããã1 æ¡ä»¥äžé ããªããŸãã ããã¯ããã¥ãŒããã¯ã¹ã¯ããŒãžã£ãåšå²ã®ç¶æ ããã£ããã£ããå¿ èŠããããšããäºå®ïŒç¹ã«ãä¿è·ããããªãœãŒã¹ãžã®åç §ããã£ããã£ããïŒã§ããããã®ãã£ããã£ã¯åçã¡ã¢ãªã§ã®ã¯ããŒãžã£ã³ã³ããã¹ãã®äœ¿çšãæå³ããŸãã Swiftãã¹ã¿ãã¯äžã®éãšã¹ã±ãŒãã¯ããŒãžã£ãŒãæé©åããæ©äŒãåŸããŸã§ãã¯ããŒãžã£ãŒãåçã¡ã¢ãªã«é 眮ããäœåãªã³ã¹ããåé¿ããå¯äžã®æ¹æ³ã¯ãã¯ããŒãžã£ãŒãçµã¿èŸŒã¿ã«ããããšã§ãã æ®å¿µãªãããããã¯ãDispatchã¢ãžã¥ãŒã«ã®å¢çãªã©ãã¢ãžã¥ãŒã«ã®å¢çå ã§ã¯äžå¯èœã§ãã ããã«ããã
DispatchQueue.sync
ãSwiftã§äžå¿ èŠã«é ããã¥ãŒããã¯ã¹ã«ãªããŸãã
次ã«æããã
objc_sync_enter
ãªãã·ã§ã³ã¯
objc_sync_enter
/
objc_sync_exit
ã§ãã libdispatchããã2ã3åé«éã§ãããçæ³ãããããé ãïŒåžžã«åå ¥å¯èœãªãã¥ãŒããã¯ã¹ã§ããããïŒãObjective-Cã©ã³ã¿ã€ã ã«äŸåããŸãïŒãããã£ãŠãAppleãã©ãããã©ãŒã ã«éå®ãããŸãïŒã
ãã¥ãŒããã¯ã¹ã®æéãªãã·ã§ã³ã¯
OSSpinLock
ã¯
dispatch_sync
ããã20å以äžé«éã§ãã ã¹ãã³ããã¯ã®äžè¬çãªå¶éïŒè€æ°ã®ã¹ã¬ãããåæã«å ¥ãããšãããšCPUã®è² è·ãé«ããªãïŒã«å ããŠã iOSã«ã¯æ·±å»ãªåé¡ãããããã®ãã©ãããã©ãŒã ã§ã®äœ¿çšã«ã¯ãŸã£ããäžé©åã§ãã ãããã£ãŠãMacã§ã®ã¿äœ¿çšã§ããŸãã
iOS 10ãŸãã¯macOS 10.12ããŸãã¯ããããæ°ãããã®ãã¿ãŒã²ããã«ããŠããå Žåã¯ã
os_unfair_lock_t
ã䜿çšã§ããŸãã ãã®ããã©ãŒãã³ã¹ãœãªã¥ãŒã·ã§ã³ã¯
OSSpinLock
ã«è¿ããæãé倧ãªåé¡ã
OSSpinLock
ããå¿ èŠããããŸãã ãã ãããã®ããã¯ã¯FIFOã§ã¯ãããŸããã 代ããã«ããã¥ãŒããã¯ã¹ã¯ä»»æã®æåŸ ïŒã€ãŸãããunfiarãïŒã«æäŸãããŸãã ãããããã°ã©ã ã®åé¡ã§ãããã©ãããå€æããå¿ èŠããããŸãããäžè¬ã«ããã®ãªãã·ã§ã³ã¯æ±çšãã¥ãŒããã¯ã¹ã®æåã®éžæè¢ã§ã¯ãªãããšãæå³ããŸãã
ãããã®åé¡ã¯ãã¹ãŠã
pthread_mutex_lock
/
pthread_mutex_unlock
å¯äžã®ã¹ããŒãã§å¹ççã§ç§»æ€å¯èœãªãªãã·ã§ã³ã«ããŸãã
ãã¥ãŒããã¯ã¹ãšèœãšãç©Žãã£ããã£åè·¯
çŽç²ãªCã®ã»ãšãã©ã®ãã®ãšåæ§ã«ã
pthread_mutex_t
ã«ã¯ããªãäžæ Œå¥œãªã€ã³ã¿ãŒãã§ãŒã¹ããããSwiftã©ãããŒã䜿çšããã®ã«åœ¹ç«ã¡ãŸãïŒç¹ã«ãã«ããšèªåã¯ãªãŒãã³ã°ã®ããïŒã ããã«ããã¹ã³ãŒãä»ãããã¥ãŒããã¯ã¹ã䜿çšãããšäŸ¿å©ã§ãããã¥ãŒããã¯ã¹ã¯ãé¢æ°ãåãå ¥ããŠãã¥ãŒããã¯ã¹å ã§å®è¡ããé¢æ°ã®äž¡åŽã§ãã©ã³ã¹ã®ãšãããããã¯ããšãããã¯è§£é€ããæäŸããŸãã
ã©ãããŒã«
PThreadMutex
ã 以äžã¯ããã®ã©ãããŒã§ã®åçŽãªã¹ã³ãŒããã¥ãŒããã¯ã¹é¢æ°ã®å®è£ ã§ãã
public func sync<R>(execute: () -> R) -> R { pthread_mutex_lock(&m) defer { pthread_mutex_unlock(&m) } return execute() }
éãåäœããã¯ãã§ãããããã§ã¯ãããŸããã çç±ãããããŸããïŒ
ãã®åé¡ã¯ãå¥ã®
CwlUtils
ã¢ãžã¥ãŒã«ã§æ瀺ããããããªåå©çšå¯èœãªé¢æ°ã®å®è£ ããçºçããŸãã ããã«ããã
DispatchQueue.sync
ã®å ŽåãšãŸã£ããåãåé¡ãçºçããŸããã¯ããŒãžã£ãŒãã£ããã£ã®çµæãåçã¡ã¢ãªãå²ãåœãŠãããŸãã ãã®ããã»ã¹äžã®ãªãŒããŒãããã«ãããé¢æ°ã¯å¿ èŠä»¥äžã«10å以äžé ãåäœããŸãïŒçæ³çãª0.263ç§ãšæ¯èŒããŠã1000äžåã®åŒã³åºãã§3.124ç§ïŒã
ããã£ããã£ããšã¯äœã§ããïŒ æ¬¡ã®äŸãèŠãŠã¿ãŸãããã
mutex.sync { doSomething(&protectedMutableState) }
ãã¥ãŒããã¯ã¹å ã§äœã䟿å©ãªããšãè¡ãã«ã¯ã
protectedMutableState
ãžã®åç §ãåçã¡ã¢ãªã®ããŒã¿ã§ãããã¯ããŒãžã£ã³ã³ããã¹ããã«æ ŒçŽããå¿ èŠããããŸãã
ããã¯ååç¡å®³ã«èŠãããããããŸããïŒçµå±ããã£ããã£ã¯ã¯ããŒãžã£ãè¡ãããšã§ãïŒã ãã ãã
sync
é¢æ°ãåŒã³åºããã®ã«åã蟌ãããšãã§ããªãå ŽåïŒå¥ã®ã¢ãžã¥ãŒã«ãŸãã¯ãã¡ã€ã«ã«ãããã¢ãžã¥ãŒã«å šäœã®æé©åããªãã«ãªã£ãŠããããïŒããã£ããã£äžã«åçã¡ã¢ãªãå²ãåœãŠãããŸãã
ããããããã¯æãŸãããããŸããã ãããåé¿ããã«ã¯ãã¯ããŒãžã£ããã£ããã£ãã代ããã«ãã¯ããŒãžã£ã«é©åãªãã©ã¡ãŒã¿ãæž¡ããŸãã
èŠå ïŒæ¬¡ã®ããã€ãã®ã³ãŒãäŸã¯ãŸããŸããããããªãã€ã€ãããã»ãšãã©ã®å Žåããããã«åŸããªãããšããå§ãããŸãã åé¡ã®æ·±ãã瀺ãããã«ãããè¡ã£ãŠããŸãã ããã®ä»ã®ã¢ãããŒããã®ç« ãèªãã§ãå®éã«äœ¿çšããŠãããã®ã確èªããŠãã ããã
public func sync_2<T>(_ p: inout T, execute: (inout T) -> Void) { pthread_mutex_lock(&m) defer { pthread_mutex_unlock(&m) } execute(&p) }
ããã¯è¯ãã§ã...ä»ãé¢æ°ã¯ãã«ã¹ããŒãã§åäœããŸãïŒ1000äžåã®åŒã³åºãã®ãã¹ãã§0.282ç§ïŒã
é¢æ°ã«ãã£ãŠæž¡ãããå€ã䜿çšããŠåé¡ã解決ããŸããã åæ§ã®åé¡ãçµæãè¿ããšãã«çºçããŸãã 次ã®æ©èœïŒ
public func sync_3<T, R>(_ p: inout T, execute: (inout T) -> R) -> R { pthread_mutex_lock(&m) defer { pthread_mutex_unlock(&m) } return execute(&p) }
ã¯ããŒãžã£ãäœããã£ããã£ããªãå Žåã§ããå ã®é床ãšåãäœéã瀺ããŸãïŒ1.371ç§ã§ãé床ã¯ããã«äœäžããŸãïŒã çµæãåŠçããããã«ããã®ã¯ããŒãžã£ãŒã¯åçã¡ã¢ãªå²ãåœãŠãå®è¡ããŸãã
çµæã«
inout
ãã©ã¡ãŒã¿ãå°å ¥ããããšã§ãããä¿®æ£ã§ããŸãã
public func sync_4<T, U>(_ p1: inout T, _ p2: inout U, execute: (inout T, inout U) -> Void) -> Void { pthread_mutex_lock(&m) execute(&p, &p2) pthread_mutex_unlock(&m) }
ããåŒã¶
// , `mutableState` `result` , mutex.sync_4(&mutableState, &result) { $1 = doSomething($0) }
ãã«ã¹ããŒãã«æ»ãããããã«ååã«è¿ã¥ããŠããŸãïŒ1000äžåã®åŒã³åºãã«å¯ŸããŠ0.307ç§ïŒã
å¥ã®ã¢ãããŒã
ããã¯åè·¯ã®å©ç¹ã®1ã€ã¯ãèŠãç®ã軜ãããšã§ãã ãã£ããã£å ã®èŠçŽ ã¯ãã¯ããŒãžã£ã®å åŽãšå€åŽã§åãååãæã¡ããããã®éã®æ¥ç¶ã¯æããã§ãã ã¯ããŒãžã£ã«ãããã£ããã£ãåé¿ãã代ããã«ãã¹ãŠã®å€ããã©ã¡ãŒã¿ãšããŠæž¡ãããšãããšããã¹ãŠã®å€æ°ã®ååãå€æŽããããã·ã£ããŠåãä»ããå¿ èŠããããŸã-ç解ã容æã«ããããšã¯ã§ããŸãã-ãããŠã誀ã£ãŠå€æ°ããã£ããã£ãããªã¹ã¯ããããŸãåã³ããã©ãŒãã³ã¹ãäœäžããŸãã
ãã¹ãŠãèã«çœ®ããå¥ã®æ¹æ³ã§åé¡ã解決ããŸãããã
ãã¡ã€ã«ã«ãã¥ãŒããã¯ã¹ããã©ã¡ãŒã¿ãŒãšããŠåãç¡æã®
sync
é¢æ°ãäœæã§ããŸãã
private func sync<R>(mutex: PThreadMutex, execute: () throws -> R) rethrows -> R { pthread_mutex_lock(&mutex.m) defer { pthread_mutex_unlock(&mutex.m) } return try execute() }
é¢æ°ãåŒã³åºããããã¡ã€ã«ã«é¢æ°ãé 眮ãããšã ã»ãšãã©ãã¹ãŠãæ©èœããŸãã å®è¡é床ã3.043ç§ãã0.374ç§ã«äœäžããäžæ¹ã§ãåçã¡ã¢ãªå²ãåœãŠã®ã³ã¹ããåãé€ããŸãã ããããçŽæ¥åŒã³åºã
pthread_mutex_lock
/
pthread_mutex_unlock
å Žåã®ããã«ããŸã 0.263ç§ã®ã¬ãã«ã«ã¯éããŠããŸããã ãŸãäœãæªãã®ã§ããããïŒ
åããã¡ã€ã«å ã«ãã©ã€ããŒãé¢æ°ãååšããŸãããSwiftã¯ãã®é¢æ°ãå®å šã«ã€ã³ã©ã€ã³åã§ããŸãããSwiftã¯
PThreadMutex
ãã©ã¡ãŒã¿ãŒïŒã³ããŒãããšãã«
pthread_mutex_t
ãå£ããªãããã«åã
class
ããïŒã®éå°ãªä¿æãšè§£æŸãæé€ããŸããã
é¢æ°ãããªãŒé¢æ°ã§ã¯ãªã
PThreadMutex
æ¡åŒµã«ããããšã«ããããããã®æšè«ãšãªãªãŒã¹ãã³ã³ãã€ã©ãŒã«åé¿ãããããšãã§ããŸãã
extension PThreadMutex { private func sync<R>(execute: () throws -> R) rethrows -> R { pthread_mutex_lock(&m) defer { pthread_mutex_unlock(&m) } return try execute() } }
ããã«ãããSwiftã¯
self
ãã©ã¡ãŒã¿ãŒã
@guaranteed
ãšããŠ
@guaranteed
ãä¿ç/解æŸã®ã³ã¹ããæé€ããæçµçã«0.264ç§ã®å€ãååŸããŸãã
ãã¥ãŒããã¯ã¹ã§ã¯ãªãã»ããã©ïŒ
ãªã
dispatch_semaphore_t
䜿çš
dispatch_semaphore_t
ãªãã®ã§ããïŒ
dispatch_semaphore_wait
ãš
dispatch_semaphore_signal
ã®å©ç¹ã¯ãã¯ããŒãžã£ãŒãå¿ èŠãšããªãããšã§ã-ãããã¯å¥ã ã®ãã¹ã³ãŒãã®ãªãåŒã³åºãã§ãã
dispatch_semaphore_t
ã䜿çš
dispatch_semaphore_t
ãŠããã¥ãŒããã¯ã¹ã®ãããªæ§é ãäœæã§ããŸãã
public struct DispatchSemaphoreWrapper { let s = DispatchSemaphore(value: 1) init() {} func sync<R>(execute: () throws -> R) rethrows -> R { _ = s.wait(timeout: DispatchTime.distantFuture) defer { s.signal() } return try execute() } }
ããã¯ã
pthread_mutex_lock
/
pthread_mutex_unlock
ãã¥ãŒããã¯ã¹ãããçŽ3åã®1 éã ïŒ0.168ç§å¯Ÿ0.244ïŒããšãããããŸããã ãã ããé床ã¯åäžããŸããããã¥ãŒããã¯ã¹ã«ã»ããã©ã䜿çšããããšã¯ãäžè¬çãªãã¥ãŒããã¯ã¹ã«æé©ãªãªãã·ã§ã³ã§ã¯ãããŸããã
ã»ããã©ã«ã¯ãå€ãã®ãšã©ãŒãåé¡ãçºçããŸãã ãããã®äžã§æãæ·±å»ãªã®ã¯ã åªå é äœå転ãã©ãŒã ã§ãã åªå é äœã®é転ã¯ã
OSSpinLock
iOSã§äœ¿çšãããåå ãšãªã£ãã®ãšåãã¿ã€ãã®åé¡ã§ãããã»ããã©ã®åé¡ã¯ããå°ãè€éã§ãã
ã¹ãã³ããã¯ãããŠããå Žåãåªå é äœã®å転ã¯æ¬¡ãæå³ããŸã
- åªå 床ã®é«ãã¹ã¬ããã¯ã¢ã¯ãã£ãã§å転ããŠãããåªå 床ã®äœãã¹ã¬ãããä¿æããŠããããã¯ã解é€ããã®ãåŸ ã£ãŠããŸãã
- åªå 床ã®äœãã¹ã¬ããã¯ãåªå 床ã®é«ãã¹ã¬ããã«ãã£ãŠäœ¿ãæãããããããããã¯ã解é€ãããããšã¯ãããŸããã
ã»ããã©ãååšããå Žåãåªå é äœã®å転ã¯æ¬¡ã®ããšãæå³ããŸãã
- åªå 床ã®é«ãã¹ã¬ãããã»ããã©ãåŸ æ©ããŸãã
- åªå é äœã¹ããªãŒã ã¯ã»ããã©ã«äŸåããŸããã
- äœåªå 床ã¹ããªãŒã ã¯ãé«åªå 床ã¹ããªãŒã ãç¶ç¶ã§ããããšãã»ããã©ã§éç¥ããããšãæåŸ ãããŸãã
äžåªå 床ã®ã¹ã¬ããã¯ãäœåªå 床ã®ã¹ã¬ããã䜿ãæãããŸãïŒããã¯ãã¹ã¬ããã®åªå 床ã§ã¯æ£åžžã§ãïŒã ããããé«åªå 床ã®ãããŒã¯äœåªå 床ã®ãããŒãã»ããã©ã§ä¿¡å·ãéãã®ãåŸ ã€ãããé«åªå 床ã®ãããŒãäžåªå 床ã®ãããŒã«ãã£ãŠæ¯æžããŸãã çæ³çã«ã¯ãããã¯èµ·ãããªãã¯ãã§ãã
ã»ããã©ã®ä»£ããã«æ£ãããã¥ãŒããã¯ã¹ã䜿çšãããå Žåãé«åªå 床ã®ã¹ããªãŒã ã®åªå 床ã¯äœåªå 床ã®ã¹ããªãŒã ã«è»¢éãããŸãããé«åªå 床ã®äººã¯äœåªå 床ã®ã¹ããªãŒã ãä¿æãããã¥ãŒããã¯ã¹ãæåŸ ããŸã-ããã«ãããäœåªå 床ã®ã¹ããªãŒã ãäœæ¥ãå®äºããé«åªå 床ã®ã¹ããªãŒã ãããã¯è§£é€ã§ããŸã ãã ããã»ããã©ã¯ã¹ããªãŒã ã«ãã£ãŠä¿æãããªããããåªå 転éã¯çºçããŸããã
æçµçã«ãã»ããã©ã¯ã¹ã¬ããéã§çµäºéç¥ãé¢é£ä»ããã®ã«é©ããæ¹æ³ã§ãïŒãã¥ãŒããã¯ã¹ã§ã¯ç°¡åã§ã¯ãããŸããïŒããã»ããã©ã®èšèšã¯è€éã§ãªã¹ã¯ã䌎ããããäºåã«é¢ä¿ãããã¹ãŠã®ã¹ã¬ãããç¥ã£ãŠããç¶æ³ã«äœ¿çšãå¶éããå¿ èŠããããŸãããã³ãã®åªå é äœâåŸ æ©äžã®ã¹ããªãŒã ã®åªå é äœãã·ã°ããªã³ã°ã¹ããªãŒã ã®åªå é äœä»¥äžã§ããããšãããã£ãŠããå Žåã
ããªãã¯ããããããªãã®ããã°ã©ã ã§ç°ãªãåªå 床ãæã€ã¹ã¬ãããæå³çã«äœæããªãã®ã§ãããã¯å°ãæ··ä¹±ããŠããããã«èŠãããããããŸããã ãã ããCocoaãã¬ãŒã ã¯ãŒã¯ã¯å°ãè€éã«ãªããŸããã©ãã§ããã£ã¹ããããã¥ãŒã䜿çšããåãã¥ãŒã«ã¯ãQoSã¯ã©ã¹ãããããŸãã ãŸããããã«ããããã¥ãŒãç°ãªãã¹ã¬ããåªå 床ã§åäœããå¯èœæ§ããããŸãã ããã°ã©ã å ã®åã¿ã¹ã¯ïŒCocoaãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠãã¥ãŒã«å ¥ãããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããã®ä»ã®ã¿ã¹ã¯ãå«ãïŒã®ã·ãŒã±ã³ã¹ãããããªãå Žåãçªç¶ãã«ãã¹ã¬ããã®åªå é äœãçºçããå¯èœæ§ããããŸãã ããã¯é¿ããã®ãæåã§ãã
ç³èŸŒã¿
PThreadMutex
ãš
DispatchSemaphore
å®è£ ãå«ããããžã§ã¯ãã¯ã Githubã§å ¥æã§ããŸãã
CwlMutex.swiftãã¡ã€ã«ã¯å®å šã«ç¬ç«ããŠãããããå¿ èŠãªå Žåã¯åçŽã«ã³ããŒã§ããŸãã
ãŸãã¯ã ReadMe.mdãã¡ã€ã«ã«ã¯ããªããžããªå šäœã®ã¯ããŒã³äœæãšããããžã§ã¯ãã«äœæãããã¬ãŒã ã¯ãŒã¯ã®è¿œå ã«é¢ãã詳现æ å ±ãå«ãŸããŠããŸãã
ãããã«
Swiftã§MacãšiOSã®äž¡æ¹ã«æé©ã§å®å šãªãã¥ãŒããã¯ã¹ãªãã·ã§ã³ã¯pthread_mutex_tã§ãã å°æ¥çã«ã¯ãSwiftã¯ãããããã¹ã¿ãã¯äžã®éãšã¹ã±ãŒãã¯ããŒãžã£ãŒãæé©åããããã¢ãžã¥ãŒã«ã®å¢çãè¶ããŠã€ã³ã©ã€ã³åããæ©äŒãåŸãã§ãããã ãããã®æ©èœã¯ãããããããããDispatch.syncã®åºæã®åé¡ãä¿®æ£ãããããããããããè¯ããªãã·ã§ã³ã«ããŸãã ãããä»ã®ãšãããããã¯éå¹ççã§ãã
ã»ããã©ããã®ä»ã®ã軜ããããã¯ã¯ãããã€ãã®ã·ããªãªã§ã¯åççãªã¢ãããŒãã§ããããããã¯æ±çšãã¥ãŒããã¯ã¹ã§ã¯ãªããèšèšæã«è¿œå ã®èæ ®äºé ãšãªã¹ã¯ã䌎ããŸãã
ã©ã®ãã¥ãŒããã¯ã¹ãšã³ãžã³ãéžæãããã«ããããããããã©ãŒãã³ã¹ãæ倧åããããã«ã€ã³ã©ã€ã³åãæäŸããéã«ã¯æ³šæããå¿ èŠããããŸããããããªããšãã¯ããŒãžã£ãŒã«ããéå°ãªãã£ããã£ã«ããããã¥ãŒããã¯ã¹ã10åé ããªãå¯èœæ§ããããŸãã Swiftã®çŸåšã®ããŒãžã§ã³ã§ã¯ãã³ãŒãã䜿çšãããŠãããã¡ã€ã«ã«ã³ãŒããã³ããŒããŠè²Œãä»ããããšãæå³ããå ŽåããããŸãã
ã¹ããªãŒãã³ã°ã®å®è¡ãã€ã³ã©ã€ã³åãæé©åã¯ãã¹ãŠãSwift 3以å€ã®éèŠãªå€æŽãäºæ³ããããããã¯ã§ãããã ããçŸåšã®SwiftãŠãŒã¶ãŒã¯Swift 2.3ããã³Swift 3ã§äœæ¥ããå¿ èŠããããŸããã¹ã³ãŒãä»ããã¥ãŒããã¯ã¹ã䜿çšããå Žåã®æ倧ããã©ãŒãã³ã¹ã
è¿œå ïŒããã©ãŒãã³ã¹ææš
åçŽãªãµã€ã¯ã«ã1000äžåå®è¡ãããŸããããã¥ãŒããã¯ã¹ãå ¥åããã«ãŠã³ã¿ãŒãå¢ããããã¥ãŒããã¯ã¹ãåºåããŸããã ãé ããããŒãžã§ã³ã®DispatchSemaphoreããã³PThreadMutexã¯ããã¹ãã³ãŒããšã¯å¥ã«ãåçæ§é ã®äžéšãšããŠã³ã³ãã€ã«ãããŸããã
çµæïŒ
ãã¥ãŒããã¯ã¹ãªãã·ã§ã³ | ç§ïŒSwift 2.3ïŒ | ç§ïŒã¹ã€ãã3ïŒ |
---|---|---|
PThreadMutex.syncïŒã¯ããŒãžã£ã«ãããã£ããã£ïŒ | 3,043 | 3,124 |
DispatchQueue.sync | 2,330 | 3,530 |
PThreadMutex.sync_3ïŒçµæãè¿ãïŒ | 1,371 | 1,364 |
objc_sync_enter | 0.869 | 0.833 |
syncïŒPThreadMutexïŒïŒåããã¡ã€ã«å ã®é¢æ°ïŒ | 0.374 | 0.387 |
PThreadMutex.sync_4ïŒããã«å ¥åãã©ã¡ãŒã¿ïŒ | 0,307 | 0.310 |
PThreadMutex.sync_2ïŒåäžã®inoutãã©ã¡ãŒã¿ãŒïŒ | 0.282 | 0.284 |
PThreadMutex.syncïŒã€ã³ã©ã€ã³ã®éãã£ããã£ïŒ | 0.264 | 0.265 |
çŽæ¥åŒã³åºãpthread_mutex_lock / unlock | 0.263 | 0.263 |
OSSpinLockLock | 0,092 | 0.108 |
䜿çšããããã¹ãã³ãŒãã¯é¢é£ããCwlUtilsãããžã§ã¯ãã®äžéšã§ããããããã®ããã©ãŒãã³ã¹ãã¹ããå«ããã¹ããã¡ã€ã«ïŒCwlMutexPerformanceTests.swiftïŒã¯ããã©ã«ãã§ã¯ãã¹ãã¢ãžã¥ãŒã«ã«æ¥ç¶ãããŠããªããããæå³çã«å«ããå¿ èŠããããŸãã