Jason. Cała informatyka w jednym miejscu!

Nadchodzi wiedza o słówku "inline" w języku Kotlin, drodzy moi! Poznacie wszyscy czym jest "funkcja wplatana" i co nam może zaoferować. Dowiecie się także jaką to przynosi zaletę, jak i wadę. Czy muszę dalej przekonywać?

"INLINE" W JĘZYKU KOTLIN JEST KOLEJNYM NAWIĄZANIEM DO HISTORII

Jestem zmuszony jeszcze raz wypowiedzieć się o języku C i o słowie kluczowym noszącym tę samą nazwę. Historii już dawno znajoma jest funkcja wplatana i słowo kluczowe "inline", które po krótkim wywnioskowaniu można utożsamiać jako "funkcję w jednej linii". Dawniej, w czasach kiedy procesory nie były jeszcze tak rozbudowane i potężne, oszczędzało się na pamięci tak jak było to możliwe. Stosowało się takie sztuczki jak korzystanie wyłącznie z liczb całkowitych, korzystanie z typów liczb całkowitych o mniejszej liczbie bitów niż "int", przedkładanie przesunięć bitowych nad zwykłe mnożenie oraz dzielenie i wreszcie między innymi, także nakładało się modyfikator na funkcję oznaczający "wplatanie".

W Kotlinie jest to samo i "to samo" działa tak samo. To jest oznaczenie funkcji jako "wplatanej". W praktyce spowoduje to to, że w kodzie wynikowym programu (np. dla Javy będzie to kod bajtowy), wywołania tejże funkcji zostaną zastąpione żywo wklejoną treścią tej funkcji! Pociąga to za sobą dwie konsekwencje, pozytywną i negatywną. Jeśli chodzi o negatywną, to podniesie się rozmiar pliku wygenerowanego kodu wynikowego przez działania kompilatora, w zależności od liczby znalezionych wywołań (im więcej, tym gorzej). Zaś skutkiem pozytywnym będzie potencjalne zwiększenie wydajności działania programu w momencie wielokrotnego wykorzystywania funkcji w krótkim czasie, na przykład w pętli. Wywołanie funkcji jest również pewnym "ciężarem" dla CPU, ponieważ wymaga więcej cykli (taktów zegara) niż wykonanie tej samej treści funkcji bez jej wywoływania (na zewnątrz).

Świetnym miejscem do rozważenia wstawienia modyfikatora "inline" w języku Kotlin może być funkcja, w której wymaga się wprowadzenia parametru w postaci wyrażenia lambda. Pamiętajmy o tym, że to jest pewnego rodzaju abstrakcja "z górnej półki", a wszystko co w języku można napisać znacznie łatwiej, zazwyczaj odbija się niekorzystnie na wydajności.

PRZYKŁAD KODU ŹRÓDŁOWEGO

Skoro zainteresowałem tematem, zajrzyjmy wszyscy razem do przykładu konkretnego. Przypuśćmy, że rozwiązanie postawionego problemu wymaga dziesięciu tysięcy iteracji tej naszej wymagającej funkcji, zatem budujemy pętlę "for" wewnątrz naszej funkcji ze szczególną starannością o parametry formalne w postaci liczby iteracji oraz zadania jakie trzeba wykonać w postaci wyrażenia lambda przyjmującego dwa parametry typu "Int":

fun performTask(iterations: Int, task: (iteration: Int, max: Int) -> Unit) {
	for (i in 1..iterations) {
		task(i, iterations)
	}
}

Oto kod wykorzystujący funkcje wyższego rzędu do jakichś skomplikowanych obliczeń:

val executionTime = measureTimeMillis {
	performTask(10000) { iterations, max ->
		val integersList = IntRange(iterations, max).toList()
		val summary = integersList.fold(0) { n, total -> total + n }
		
		println(summary)
	}
}

println("Czas do wykonania zadania: ${executionTime*0.001}s")

Skorzystałem z funkcji "measureTimeMillis", aby zmierzyć czas jaki upłynie dla wykonania tego bloku kodu. Dla średnio rozbudowanego procesora to może być koszmar! W dzisiejszych czasach to raczej mało prawdopodobne, aczkolwiek mogą się zdarzyć pojedyncze przypadki, a raczej nie chcielibyśmy programować aplikacji, która ten 1% ludzi będzie "zostawiać na lodzie".

Zobaczcie. Tak się oznacza funkcję modyfikatorem "inline" w języku Kotlin:

inline fun performTask(iterations: Int, task: (iteration: Int, max: Int) -> Unit) {
	for (i in 1..iterations) {
		task(i, iterations)
	}
}

Już! Nic więcej nie musimy robić, resztę zrobi za nas kompilator gdy tylko "wyłapie" o co nam chodzi. Może to POTENCJALNIE pomóc zwiększyć efektywność wykonywanych obliczeń i operacji, zamieniając wywołanie funkcji na wklejoną jej zawartość.

Słowo kluczowe "inline" w języku Kotlin

Modyfikator "inline" powoduje potraktowanie funkcji jako "wplatanej" co ma wpływ na rozmiar kodu wynikowego i POTENCJALNY wzrost efektywności wykonywania.


Żeby nie było. "inline" w języku Kotlin NIE GWARANTUJE podniesienia wydajności wykonywanych rozkazów przez procesor. W moim przypadku, to nawet pogorszyło efektywność działania (bez "inline" miałem poniżej 0,3 sekundy, a po jego wprowadzeniu miałem nawet ponad 0,4 sekundy)! Twierdzę jedynie, że to MOŻE zwiększyć efektywność jeśli jakaś funkcja zostanie poddana "wplataniu", a korzysta z szeregu różnych "ułatwiaczy" takich jak lista czy funkcja wyższego rzędu (syntaktyczny cukier).

PODOBNE ARTYKUŁY