Referencia: livro "Programming Kotlin" de Stephen Samuel e Stefan Bocutiu.
Photos by Andrea Piacquadio and Pixabay from Pexels
Olá pessoal,
Neste artigo vou compartilhar alguns recursos que aprendi para melhorar a performance do código:
1) Lazy: tem a finalidade de só invocar uma função apenas quando ela for ser usada pela primeira vez.
2) Memoization: em funções recorrentes se for necessário armazenar o resultado de cada chamada da função.
3) A keyword "tailrec": em funções recorrentes se não for necessário armazenar o resultado de cada chamada da função.
Vamos lá!
1) Lazy tem a finalidade de só invocar uma função apenas quando ela for ser usada pela primeira vez. Se você tiver uma função muito pesada, Lazy vai deixar para executá-la somente quando de fato você precisar do seu retorno em seu código. Veja o código ilustrativo abaixo:
/* Atribuindo a função "readStringFromDatabase" a uma variável. */ fun readStringFromDatabase(): String = ... // expensive operation val lazyString = lazy { readStringFromDatabase() } /* Usando o retorno da função pela primeira vez. */ val string = lazyString.value
2) Ao usarmos funções recorrentes (funções que invocam a si próprias) podemos usar a técnica de "MEMOIZATION", memorização para acelerar a execução ao fazer o caching e reutilizar o resultado de chamadas anteriores. Assim ela roda mais rápido e evita a falha de Stack Overflow.
Vamos ver a comparação entre a chamada da função de exemplo com e sem aplicação da técnica:
1ª Execução: fib(10) = 89
Tempo de execução NÃO usando Memoization com mutableMapOf(): 9 ms.
2ª Execução: memfib(100) = 1298777728820984005
Tempo de execução USANDO Memoization com mutableMapOf(): 2 ms.
fun main ( args : Array < String >) { var k = 10 var timeIni = System.currentTimeMillis() //A Função fib retorna o elemento a posição k da sequência de Fibonacci: 1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89; 144;... //Por exemplo, fib(0) = 1, fib(1) = 1, fib(2), fib(3) fun fib(k: Int): Long = when (k) { 0 -> 1 1 -> 1 else -> fib(k - 1) + fib(k - 2) } println("1ª Execução: fib($k) = ${fib(k)}") println("Tempo de execução NÃO usando Memoization com mutableMapOf() ${System.currentTimeMillis() - timeIni} ms.") // A Função memfib retorna o elemento a posição k da sequência de Fibonacci aplicando o conceito de 'MEMOIZATION' por meio de uma MutableMap. timeIni = System.currentTimeMillis() k = 100 val map = mutableMapOf<Int, Long>() fun memfib(k: Int): Long { return map.getOrPut(k) { when (k) { 0 -> 1 1 -> 1 else -> memfib(k - 1) + memfib(k - 2) } } } println("2ª Execução: memfib($k) = ${memfib(k)}") println("Tempo de execução USANDO Memoization com mutableMapOf() ${System.currentTimeMillis() - timeIni} ms.") }
Uau!!!
3) Ao usarmos funções recorrentes (funções que invocam a si próprias) podemos fazer a declararação da função recorrente usando a keyword "tailrec"; assim ela não guarda os resultados da última execução. Assim ela roda mais rápido e evita a falha de Stack Overflow.
Olha a comparação do tempo de execução nesse exemplo de duas funções que calculam o fatorial de um número inteiro:
1ª Execução:
Fatorial de 5 = 120
A função fact executou em 16 ms
2ª Execução:
Fatorial de 5 = 120
A função factFaster executou em 0 ms
O código está abaixo:
fun main(args: Array<String>) { var time = System.currentTimeMillis() var num: Int = 5 println("Fatorial de $num = ${fact(num)}") println("A função fact executou em ${System.currentTimeMillis() - time} ms\n") time = System.currentTimeMillis() println("Fatorial de $num = ${factFaster(num)}") println("A função factFaster executou em ${System.currentTimeMillis() - time} ms") } fun fact(k: Int): Int { fun factTail(m: Int, n: Int): Int { if (m == 0) return n else return factTail(m - 1, m * n) } return factTail(k, 1) } fun factFaster(k: Int): Int { tailrec fun factTail(m: Int, n: Int): Int { if (m == 0) return n else return factTail(m - 1, m * n) } return factTail(k, 1) }
Faça parte da nossa comunidade!
Domine as tecnologias utilizadas pelas empresas mais inovadoras do mundo e encare seu novo desafio profissional, evoluindo em comunidade com os melhores experts.