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ã¡ãŒãªã³ã°ãªã¹ããèªããšããã®ããšã®æç¢ºãªèšŒæ ãèŠã€ããããšãã§ããŸãã
é«éãªæ±çšãã¥ãŒããã¯ã¹ãã¥ãŒããã¯ã¹ãèŠã€ããããšããŠããŸã
ã€ãŸãããã«ãã¹ã¬ããã®åäœãå¿
èŠãªå Žåãæ¢åã®ã¹ããªãŒãã³ã°ããŒã«ãšãã¥ãŒããã¯ã¹ããããã£ã䜿çšããŠèªåã§ãã«ãããå¿
èŠããããŸãã
æšæºã®
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ïŒã¯ããã©ã«ãã§ã¯ãã¹ãã¢ãžã¥ãŒã«ã«æ¥ç¶ãããŠããªããããæå³çã«å«ããå¿
èŠããããŸãã