Hi everyone, I am DHL. ByteCode, focus on the latest technology to share original articles, involving Kotlin, Jetpack, algorithm animation, data structure, system source code, LeetCode/point Offer/multithreading/domestic and foreign large factory algorithm problems and so on.
This is the third article on value class. I have already written two articles to analyze value class from different perspectives.
-
Value class is a very useful feature that can improve code readability and performance, as described in Kotlin 1.5’s Value Class article, which examines value class and inline class in detail.
-
In this article, we analyze the performance of value classes and data classes in detail, as well as the details that need to be paid attention to when using value classes
This article will analyze value classes from the perspectives of type safety, memory footprint, execution efficiency, and usage scenarios. Through this article, you will learn the following.
- What is the
value class
? - What is the
typealias
? typealias
Type safety cannot be guaranteedtypealias
同value class
No additional objects will be createdvalue class
和typealias
Execution efficiency oftypealias
Compare with the original String typevalue class
和typealias
contrast
value class
和typealias
Advantages and usage scenarios
What is a value class
The value class represents an inline class that requires passing in a parameter to the main constructor and is decorated with val. When compiled into Java code, it is replaced with the value passed in, as shown below.
@JvmInline
value class User(val name: String)
fun login(user: User?): String = user? .name ?:""
fun testInline(a) {
println(login(User("DHL")))}// The compiled code
public static final String login_js0Jwf8/* $FF was: login-js0Jwf8*/(@Nullable String user) {
/ /...
return var10000;
}
public static final void testInline(a) {
String var0 = login-js0Jwf8("DHL");
System.out.println(var0);
}
Copy the code
As you can see, the compiled Java code does not create additional objects, but instead replaces the object User created in Kotlin with the value DHL passed in.
What is typealias
In Kotlin’s source code, expressions that encounter long signatures more or less use TypeAlias, which simply gives the class an alias.
typealias Password = String
fun inputPassword(password: Password){}fun main(a) {
val password: Password = "123456"
inputPassword(password)
}
Copy the code
Using the TypeAlias keyword, alias Password is given to the String type, and you can then use Password as if it were String.
A value class is a data class and a value class is a data class. A value class is a data class. Whether a value class can completely replace a TypeAlias.
Typealias does not guarantee type safety
A String can represent many things, such as a user name, password, and so on. We can also alias the user name and password with the TypeAlias keyword.
typealias Username = String
Copy the code
InputPassword (password: String) is of type String, so we can pass in typeAlias alias Username because the type is the same and assignment is compatible, as shown below.
fun inputPassword(password: String){}val userName: Username = "ByteCode"
inputPassword(userName)
Copy the code
Although this is a password-input function, if the caller passes in a username, assignment is compatible because the type is the same, this is not detected at compile time, but can have unpredictable consequences at run time.
The emergence of value class helps us solve this problem. We can also use data class or other classes to solve this problem, but there will be additional performance overhead. For a closer look at a few Kotlin details that were easily overlooked in previous articles, value class execution is surprisingly efficient.
@JvmInline
value class Password(val value: String) { }
fun inputPassword(password: Password){}Copy the code
Now if we pass in an unwanted parameter to the inputPassword() function, it will be checked at compile time.
Typealias, like Value Class, does not create additional objects
A Value Class does not create additional objects from a memory point of view, as does typeAlias, which is compiled as shown below.
typealias Password = String
fun inputPassword(password: Password){}// The compiled code
public static final void inputPassword(@NotNull String password) {
/ /...
}
Copy the code
The compiled code for value Class looks like this.
@JvmInline
value class Password(val value: String) { }
fun inputPassword(password: Password){} Compiled codepublic static final void inputPassword_ZVkiumU(@NotNull String password) {
/ /...
}
Copy the code
As you can see, there is no additional object creation overhead for either value Class or TypeAlias.
Value Class and TypeAlias execution efficiency
Let’s look at value Class and TypeAlias execution efficiency from the following perspectives.
typealias
Compare with the original String typevalue class
和typealias
contrastvalue class
和data class
Contrast, contrast, contrast, contrastThe articleIt has been analyzed and ignored here)
Typealias compared to the original String type
Using the typeAlias keyword to alias String Password, we use an example to verify the efficiency of the Password and the primitive String.
fun inputPassword(password: String){}fun inputPasswordTypealias(password: Password){}typealias Password = String
@ExperimentalTime
fun main(a) {
// Primitive type
val measureString = measureTime {
repeat(1000) {
inputPassword("123456")
}
}
println("measure string time ${measureString.toDouble(TimeUnit.MILLISECONDS)} ms")
// typealias
val measuretypealias = measureTime {
repeat(1000) {
inputPasswordTypealias("123456")
}
}
println("measure typealias time ${measuretypealias.toDouble(TimeUnit.MILLISECONDS)} ms")}Copy the code
We tested String and TypeAlias respectively, and their results are shown below.
measure string time 5.475575 ms
measure typealias time 5.853019 ms
Copy the code
The result is essentially the same because the compiled Java code replaces the typeAlias declaration alias with the original type String.
Value Class compares with TypeAlias
Let’s take a look at the efficiency of value Class and TypeAlias. The code is simple as follows.
// typealias
typealias Password = String
fun inputPassword(password: Password) {}
// value class
@JvmInline
value class Password(val value: String) {}
fun inputPasswordValueClass(password: Password) {}
@ExperimentalTime
fun main(a) {
// typealias
val measureString = measureTime {
repeat(1000) {
inputPassword("123456")
}
}
println("measure typealias time ${measureString.toDouble(TimeUnit.MILLISECONDS)} ms")
// value class
val measureValueClass = measureTime {
repeat(1000) {
inputPasswordValueClass(Password("123456"))
}
}
println("measure value class time ${measureValueClass.toDouble(TimeUnit.MILLISECONDS)} ms")}Copy the code
The test results for value Class and TypeAlias are shown below.
measure typealias time 6.437296 ms
measure value class time 6.66023 ms
Copy the code
As you can see, there is almost no difference between a Value class and a TypeAlias in terms of memory and performance. Is it possible to use a Value class instead of a TypeAlias entirely? This is shown to be impossible, and while value classes are efficient and powerful, they are used in completely different scenarios.
The advantages and usage scenarios of Value Class and TypeAlias
Based on the previous content and the analysis of value classes in the previous two articles, value classes have the following advantages:
- Type safety prevents callers from doing things we don’t expect
- It takes up less memory and is more efficient
- Improved code readability
value class
Is a real type that is more powerful and can have constructors, initializers, and other functions (getXXX()
、setXXX()
) and so on, so that we can encapsulate the business logic
The biggest advantage of Data class compared with value class is that it supports multiple parameters, while value class only supports one parameter declared with Val. However, value class has much higher memory and execution efficiency than data class. When there’s a lot of data, the gap gets bigger and bigger.
measure data class time 6.790241 ms
measure value class time 0.832866 ms
Copy the code
Value class has so many advantages, but what about its usage scenarios? In fact, there is no fixed usage scenario, we can use value class in Toast, conversion between units (time, distance), location, Json serialization and deserialization, etc. After we understand their advantages and disadvantages, we can consider from more dimensions such as memory and execution efficiency.
Value classes have many advantages, but in some cases TypeAliases are better than value classes. When we use higher-order functions, Lambda expressions, expressions with long signatures, typeAliases are better. An example code is shown below.
inline fun requestData(type: Int, call: (code: Int.type: Int) - >Unit) {
call(200, type)
}
Copy the code
There is a Lambda expression in the method argument, and it is possible to change the parameters in the Lambda expression at any time in the future. If the Lambda expression is given an alias through typeAlias, the alias will not only improve the readability, but also facilitate uniform modification in the future. The final code is shown below.
typealias Callback = (code: Int, type: Int) - >Unit
inline fun requestData(type: Int, call: Callback) {
call(200, type)
}
Copy the code
So when we use higher-order functions and long-signed expressions, we can consider using TypeAlias.
A “like” would be the biggest encouragement if it helps
More code, more articles
Welcome to the public account: ByteCode, continue to share the latest technology
Finally, recommend long-term update and maintenance projects:
-
Personal blog, will all articles classification, welcome to check hi-dhl.com
-
KtKit compact and practical, written in Kotlin language tool library, welcome to check KtKit
-
Androidx-jetpack-practice androidX-Jetpack-practice androidX-Jetpack-practice androidX-Jetpack-Practice androidX-Jetpack-Practice
-
LeetCode/multiple thread solution, language Java and Kotlin, including a variety of solutions, problem solving ideas, time complexity, spatial complexity analysis
- Job interview with major companies at home and abroad
- LeetCode: Read online
Must-read articles these days
- A few Kotlin details that are easy to overlook, value class execution is surprisingly efficient
- Launching a website in 1 minute – no domain name, no server – has never been easier
- Box-sizing: border-box! Important; word-wrap: break-word! Important; “> < span style =” max-width: 100%
- Android 12 is here, did your App crash?
- Kotlin announced a blockbuster feature
- Google has announced the abandonment of the LiveData.observe method
- One detail to note when using Kotlin
- Kotlin code affecting Performance (1)
- Jetpack Splashscreen parsing | power generation IT migrant workers get twice the result with half the effort
- Kotlin’s Technique and Analysis (3)
- Uncover the == and === in Kotlin
- The Kotlin hermetic class evolved