-
[SE-0523] Hashable conformance for UnownedTaskExecutorSwift 2026. 5. 15. 03:53
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 SE-0523 — UnownedTaskExecutor의 Hashable 채택에 대해 정리해보겠습니다 🙋🏻

Intro
- Proposal: SE-0523
- Authors: Fabian Fett, Konrad Malawski
- Review Manager: John McCall
- Status: Implemented (Swift 6.4)
Motivation
SE-0417에서 도입된 task executor preferences는 현재 실행 중인 task의
unownedTaskExecutor를 노출해, 성능에 민감한 코드가 executor 기반으로 스케줄링 결정을 내릴 수 있게 해줍니다.UnownedTaskExecutor는 이미Equatable을 채택하고 있어요.
그런데Hashable이 없다 보니, executor를 기준으로 리소스를 인덱싱해야 하는 경우에 불편함이 생겼습니다.대표적인 사례가 커넥션 풀링입니다.
ConnectionPool이 여러 executor에 걸쳐 커넥션을 관리할 때, task의 executor에 이미 연결된 커넥션을 우선적으로 반환하면 불필요한 컨텍스트 스위치를 줄일 수 있거든요 😁
Hashable이 없으면 executor를 찾기 위해 매번 선형 탐색을 해야 합니다 🐛Before — O(n) 선형 탐색
// Today: O(n) linear search func pickConnection(preferring executor: UnownedTaskExecutor) -> Connection { for (e, connection) in executorConnectionList { if e == executor { return connection } } return executorConnectionList.first!.connection }
After — O(1) 딕셔너리 조회// With Hashable: O(1) dictionary lookup func pickConnection(preferring executor: UnownedTaskExecutor) -> Connection { if let connection = connectionsByExecutor[executor] { return connection } return connectionsByExecutor.values.first! }이 패턴은 커넥션 풀링뿐만 아니라 executor identity를 기준으로 리소스, 캐시, 스케줄링 메타데이터를 인덱싱하는 모든 시스템에 적용될 수 있습니다.
Detailed Design
UnownedTaskExecutor는Builtin.Executor값을 감싸는 struct입니다.
이미 기저 executor 참조의 identity를 기반으로Equatable채택이 되어 있어요.Hashable채택도 동일한 identity 값을 해싱하므로, 기존 equality 시맨틱과 일관성을 완전히 유지합니다.extension UnownedTaskExecutor: Hashable {}
API 변경은 이것이 전부입니다. 딱 한 줄이에요 🙌
Source Compatibility / ABI
- 이번 변경은 순수 additive 변경으로, 기존 코드는 변경 없이 그대로 컴파일됩니다.
Equatable을 채택한 타입에Hashable을 추가하는 것은 소스 호환성을 깨지 않습니다.- 프로토콜 채택 추가는 additive ABI 변경이며, 기존 ABI 서피스를 수정하지 않습니다.
Alternatives Considered
아무것도 하지 않기
아무것도 하지 않으면, 개발자가 직접
Hashable채택을 구현해야 합니다.extension UnownedTaskExecutor: Hashable { @inlinable public func hash(into hasher: inout Hasher) { let (ident, impl) = unsafeBitCast(self, to: (Int, Int).self) hasher.combine(ident) hasher.combine(impl) } }unsafeBitCast를 직접 사용해야 한다는 점에서 불필요하게 위험하고 번거롭습니다. 표준 라이브러리 차원에서 제공하는 것이 당연히 올바른 방향이라고 생각합니다.
Conclusion
아주 작은 변경이지만, 굉장히 자연스러운 확장입니다 🙌
Equatable을 채택하고 있는 타입이라면Hashable도 당연히 지원해야 한다는 Swift의 설계 철학에 맞게,UnownedTaskExecutor도 이제 딕셔너리 키와 Set으로 자유롭게 활용할 수 있게 됩니다!executor 기반으로 리소스를 관리하는 코드를 작성하고 계신 분들께 특히 반가운 소식일 것 같습니다 😄
References
swift-evolution/proposals/0523-hashable-unownedtask-executor.md at main · swiftlang/swift-evolution
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution
github.com
'Swift' 카테고리의 다른 글
[SE-0522] Source-Level Control Over Compiler Warnings (0) 2026.05.23 [SE-0524] Add withTemporaryAllocation using Output(Raw)Span (1) 2026.05.09 [SE-0521] Improved Syntax for Optionals of Opaque and Existential Types (0) 2026.05.01 [SE-0520] Discardable result use in Task initializers (0) 2026.04.25 [SE-0519] Borrow and Inout types for safe, first-class references (2) 2026.04.11