๊ธ€ ์ž‘์„ฑ์ž: ๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด
 

Increasing Performance by Reducing Dynamic Dispatch - Swift Blog

Get the latest news and helpful tips on the Swift programming language from the engineers who created it.

developer.apple.com

Dynamic Dispatch

Dynamic Dispatch์˜ ์‚ฌ์šฉ์ด ๋ฌด์กฐ๊ฑด ๋‚˜์œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. Dynamic Dispatch ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋„ ํ•  ์ˆ˜ ์žˆ๊ณ , ๋‹คํ˜•์„ฑ๋„ ๋งŒ๋“ค์ˆ˜ ์žˆ๊ณ  ์ƒ์†๋„ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ๊นŒ์š”. ํ•˜์ง€๋งŒ ๋ฐ˜๋“œ์‹œ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋” ์ด์ƒ ์ƒ์†ํ•  ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์—†๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”? 

 

Dynamic Dispatch๋Š” ์‹ค์ œ ๊ตฌํ˜„์ฝ”๋“œ๋ฅผ ์ฐพ์•„๊ฐ€๊ธฐ ์œ„ํ•ด ํ…Œ์ด๋ธ”์„ ํƒ์ƒ‰ํ•ด์•ผํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํด๋ž˜์Šค์—์„œ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ๊ฐ€ ๋ช…ํ™•ํ•˜๋‹ค๋ฉด ๊ตณ์ด Dynamic Dispatch๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ฒ ์ฃ . 

 

์• ํ”Œ ๊ณต์‹ ๋ธ”๋กœ๊ทธ์—์„œ ์•Œ๋ ค์ฃผ๋Š” ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ํ•œ๋ฒˆ ์•Œ์•„๋ด…์‹œ๋‹ค!

class ParticleModel {
	var point = ( 0.0, 0.0 )
	var velocity = 100.0

	func updatePoint(newPoint: (Double, Double), newVelocity: Double) {
		point = newPoint
		velocity = newVelocity
	}

	func update(newP: (Double, Double), newV: Double) {
		updatePoint(newP, newVelocity: newV)
	}
}

var p = ParticleModel()
for i in stride(from: 0.0, through: 360, by: 1.0) {
	p.update((i * sin(i), i), newV:i*1000)
}

์ด ์ฝ”๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ Dynamic Dispatch๋ฅผ ์ค„์—ฌ๋ณผ๊ฑฐ์˜ˆ์š”!

 

๋ฐฉ๋ฒ•1: ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ํ•„์š”์—†๋‹ค๋ฉด final์„ ์‚ฌ์šฉํ•˜์„ธ์š”!

final ํ‚ค์›Œ๋“œ๋ฅผ ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ํ”„๋กœํผํ‹ฐ์— ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€์ƒ์ด ๋” ์ด์ƒ ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋  ์ˆ˜ ์—†๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ œํ•œ๋œ ๋Œ€์ƒ๋“ค์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‰ฝ๊ฒŒ ์–ด๋–ค ๋ฉ”์„œ๋“œ๋‚˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ํƒํ•ด์•ผํ• ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Static Dispatch๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒํ•ด์ค๋‹ˆ๋‹ค.

class ParticleModel {
	final var point = ( x: 0.0, y: 0.0 )
	final var velocity = 100.0

	final func updatePoint(newPoint: (Double, Double), newVelocity: Double) {
		point = newPoint
		velocity = newVelocity
	}

	func update(newP: (Double, Double), newV: Double) {
		updatePoint(newP, newVelocity: newV)
	}
}

์ด์ œ point, velocity ํ”„๋กœํผํ‹ฐ์™€ updatePoint ๋ฉ”์„œ๋“œ๋Š” final๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ์ œํ•œ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— Static Dispatch๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— update ๋ฉ”์„œ๋“œ๋Š” ๊ทธ๋Œ€๋กœ Dynamic Dispatch ์ด๊ฒ ์ฃ ? ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ํ•˜๊ฒŒ๋˜๋ฉด ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผํ• ์ง€ ๋ถˆ๋ถ„๋ช…ํ•ด์ง€๋‹ˆ๊นŒ์š”.

 

ํด๋ž˜์Šค ์ „์ฒด์— final ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ค„ ์ˆ˜๋„ ์žˆ์–ด์š”.

final class ParticleModel {
	var point = ( x: 0.0, y: 0.0 )
	var velocity = 100.0
	// ...
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด ํด๋ž˜์Šค๋Š” ์ด์ œ ์ƒ์†์ด ์•„์˜ˆ ๋ถˆ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋“ค์ด final์„ ๊ฐ€์ง„๊ฒƒ๊ณผ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ํด๋ž˜์Šค์— ๋Œ€ํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ํ˜ธ์ถœ์€ Static Dispatch๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐฉ๋ฒ• 2: private์„ ์‚ฌ์šฉํ•˜์„ธ์š”!

private์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค์˜ ์„ ์–ธ๋ถ€ ์™ธ๋ถ€์—์„œ๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋‚˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณผ ์ˆ˜์กฐ์ฐจ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋‚˜ ํ”„๋กœํผํ‹ฐ๋“ค์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‰ฝ๊ฒŒ Static Dispatch๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. 

class ParticleModel {
	private var point = ( x: 0.0, y: 0.0 )
	private var velocity = 100.0

	private func updatePoint(newPoint: (Double, Double), newVelocity: Double) {
		point = newPoint
		velocity = newVelocity
	}

	func update(newP: (Double, Double), newV: Double) {
		updatePoint(newP, newVelocity: newV)
	}
}

์ด๋ ‡๊ฒŒ ์›ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ์— private์„ ๋ถ™์ด๊ฑฐ๋‚˜,

private class ParticleModel {
	var point = ( x: 0.0, y: 0.0 )
	var velocity = 100.0
	// ...
}

ํด๋ž˜์Šค ์ „์ฒด์— private์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์–ด์š”. ์ด๋Ÿฐ ์„ ์–ธ์€ ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์— private ์ ‘๊ทผ ์ œ์–ด๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐฉ๋ฒ• 3: Whole Module Optimization์„ ์‚ฌ์šฉํ•˜๋ฉด final์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Whole Module Optimization์€ ๋ชจ๋“ˆ ์ „์ฒด๋ฅผ ํ•œ๋ฒˆ์— ์ปดํŒŒ์ผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ ์ ‘๊ทผ์ œ์–ด์ž์ธ internal๋กœ ์„ ์–ธ๋œ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ผ๋„ ์ „์ฒด ๋ชจ๋“ˆ์—์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” internal ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ final๋กœ ์ถ”๋ก ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Static Dispatch๋กœ ๋™์ž‘ํ•˜๊ฒŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class ParticleModel {
	var point = ( x: 0.0, y: 0.0 )
	var velocity = 100.0

	func updatePoint(newPoint: (Double, Double), newVelocity: Double) {
		point = newPoint
		velocity = newVelocity
	}

	public func update(newP: (Double, Double), newV: Double) {
		updatePoint(newP, newVelocity: newV)
	}
}

var p = ParticleModel()
for i in stride(from: 0.0, through: times, by: 1.0) {
	p.update((i * sin(i), i), newV:i*1000)
}

์ด ์ฝ”๋“œ์—์„œ internal๋กœ ์„ ์–ธ๋œ point, velocity, updatePoint๋Š” ์ด์ œ ๋ชจ๋“  ํŒŒ์ผ์ด ํ•œ๋ฒˆ์— ์ปดํŒŒ์ผ๋˜๋ฉด์„œ ์ด ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋Š” ์˜์—ญ์ด ๋ชจ๋“ˆ ๋‚ด์— ์—†์Œ์„ ์•Œ๊ณ  final๋กœ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Static Dispatch๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ update ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” public ์œผ๋กœ ์„ ์–ธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€ ๋ชจ๋“ˆ์—๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด final๋กœ ์ถ”๋ก ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. 

(๋ผ๊ณ  ํ•ด์„์ด ๋˜๋Š”๋ฐ public์€ ์™ธ๋ถ€ ๋ชจ๋“ˆ์—์„œ ์„œ๋ธŒํด๋ž˜์‹ฑ์„ ํ—ˆ์šฉ์•ˆํ•˜์ง€ ์•Š๋‚˜์š”..? 3๋ฒˆ์งธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ช…ํ™•ํ•˜๊ฒŒ ์•„์‹ ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”ใ… ใ…œ)

 

๋งˆ์ง€๋ง‰ ๋ฐฉ๋ฒ•์ด ์ข€ ์ฐ์ฐํ•˜๋„ค์š”.. open ์ด๋ผ๋ฉด ๋ช…๋ฐฑํ•˜๊ฒŒ Dynamic Dispatch์ผํ…๋ฐ..

 

https://stackoverflow.com/questions/56341501/why-cant-whole-module-optimalization-infer-final-on-public-non-overridden-modul

 

Why can't Whole Module Optimalization infer final on public non-overridden module classes/methods in the same module?

From this article, I quote the following sentence: Use Whole Module Optimization to infer final on internal declarations. Declarations with internal access (the default if nothing is declared)...

stackoverflow.com

์ฐพ์•˜์Šต๋‹ˆ๋‹ค..ใ…‹ใ…‹ใ…‹ 

 

์ € ๊ธ€์ด ๋‚˜์˜จ๊ฒŒ Swift2์—์„œ ๋‚˜์™€์„œ public ์ด open ์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋  ๋•Œ์˜€๋‹ค๊ณ  ํ•˜๋„ค์š”..! open์ด ์•„๋‹ ๋•Œ๋งŒ final๋กœ ์ถ”๋ก ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค! open์€ Swift3์—์„œ ์†Œ๊ฐœ๋˜์—ˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.