This vs it receiver difference in Kotlin - Performance Comparison
We want to understand how the use of different receivers like this and it affects the number of operations in Kotlin code.
Specifically, how does choosing one receiver over the other change the work done as input grows?
Analyze the time complexity of the following Kotlin code using this and it receivers.
fun List<Int>.sumWithThis(): Int {
var total = 0
this.forEach { total += it }
return total
}
fun List<Int>.sumWithIt(): Int {
var total = 0
for (item in this) {
total += item
}
return total
}
Both functions add up all numbers in a list, but use this and it differently.
Look at what repeats as the list size grows.
- Primary operation: Adding each number to
total. - How many times: Once for every item in the list.
As the list gets bigger, the number of additions grows directly with the list size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions |
| 100 | 100 additions |
| 1000 | 1000 additions |
Pattern observation: The work grows evenly as the list grows, no matter if this or it is used.
Time Complexity: O(n)
This means the time to add all numbers grows in a straight line with the list size, regardless of using this or it.
[X] Wrong: "Using this is slower or faster than it because it changes how many times the code runs."
[OK] Correct: Both receivers just name the current item or object. They don't add extra loops or operations. The number of times the code runs depends only on the list size.
Understanding how different ways to refer to data affect performance helps you write clear and efficient Kotlin code. It shows you can focus on what matters most: the size of your data, not small syntax choices.
What if we replaced the forEach loop with a recursive function using this or it? How would the time complexity change?
Practice
this refer to inside a class method?Solution
Step 1: Understand
Inside a class method,thisin class contextthisrefers to the current object instance that called the method.Step 2: Differentiate from lambda parameter
thisis not a lambda parameter; that role is usually played byitin single-parameter lambdas.Final Answer:
The current instance of the class -> Option AQuick Check:
thisin class = current object [OK]
this means current object in classes [OK]- Confusing
thiswith lambda parameterit - Thinking
thisis a global variable - Assuming
thisrefers to static context
Solution
Step 1: Identify default lambda parameter
In Kotlin, when a lambda has a single parameter and no explicit name, it is referred to asit.Step 2: Confirm
thisis not used herethisrefers to the receiver object, not the lambda parameter.Final Answer:
it -> Option BQuick Check:
Single lambda parameter =it[OK]
it [OK]- Using
thisinstead ofitin lambdas - Trying to name the parameter without declaration
- Assuming
selfis valid in Kotlin
class Box(val value: Int) {
fun printValue() {
listOf(1).forEach {
println(this.value + it)
}
}
}
fun main() {
Box(5).printValue()
}Solution
Step 1: Understand
Insidethisinside lambda with receiverprintValue,thisrefers to theBoxinstance, sothis.valueis 5.Step 2: Calculate the sum inside lambda
The lambda parameteritis 1 from the list. So,this.value + it = 5 + 1 = 6.Final Answer:
6 -> Option AQuick Check:
this.value + it= 6 [OK]
this is outer object, it is lambda param [OK]- Thinking
thisrefers to lambda receiver - Confusing
itwiththis - Expecting compilation error due to
thisusage
fun main() {
val numbers = listOf(1, 2, 3)
numbers.forEach {
println(this + it)
}
}Solution
Step 1: Check
In this lambda, there is no receiver object, sothisusage inside lambdathisis not defined and causes an error.Step 2: Confirm lambda parameter usage
itis valid as the lambda parameter, butthiscannot be used without a receiver context.Final Answer:
Usingthisinside lambda without receiver causes error -> Option CQuick Check:
thisneeds receiver, else error [OK]
this inside lambda [OK]- Assuming
thisalways refers to lambda parameter - Ignoring that
thisrequires receiver context - Thinking code runs without error
class Calculator {
fun calculate() {
val numbers = listOf(10, 20)
numbers.run {
println(this.sum())
numbers.forEach {
println(it + this.sum())
}
}
}
}
fun main() {
Calculator().calculate()
}Solution
Step 1: Understand
Insidethisinsiderunblockrun,thisrefers to thenumberslist. So,this.sum()is 30.Step 2: Calculate outputs inside
For eachforEachitinnumbers(10 and 20), printit + this.sum(): 10+30=40 and 20+30=50.Step 3: List all printed lines
First print: 30
Then prints: 40 and 50Final Answer:
30 40 50 -> Option DQuick Check:
thisinrun= list, sum=30 [OK]
run, this is receiver object [OK]- Confusing
thisinside nested lambdas - Assuming
thisrefers to Calculator instance - Expecting compilation error due to
this
Ready to prove it?
Pass the test and this pattern moves unknown
