Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit 4a73635

Browse files
authored
Merge pull request #18 from k163377/fix_readme_and_benchmark
Fix readme and benchmark.
2 parents 90eddb3 + b70a2bf commit 4a73635

File tree

3 files changed

+160
-150
lines changed

3 files changed

+160
-150
lines changed

README.md

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,43 @@ val result: Sample = fastKFunction.generateBucket()
3737
```
3838

3939
## How Fast?
40-
Calling the constructor is more than 1.2 times faster than calling `KFunction` with `call`,
40+
Calling the `constructor` is more than 1.2 times faster than calling `KFunction` with `call`,
4141
and more than 6 times faster than calling it with `callBy`.
4242

4343
You can get the same speed as `reflection` in `Java`.
4444

45-
| | ops/s |Ratio|
46-
|-----------------------|------------:|-----|
47-
| Java Constructor |`104267558.4`|`6.7`|
48-
| FastKFunction(call) |`102948283.4`|`6.6`|
49-
| FastKFunction(callBy) |`105609306.2`|`6.8`|
50-
| KFunction(call) | `77096714.2`|`5.0`|
51-
| KFunction(callBy) | `15519730.2`|`1` |
45+
| | ops/s |Ratio|
46+
|---------------------------|------------:|-----|
47+
| **Java Constructor** |`104267558.4`|`6.7`|
48+
| **FastKFunction(call)** |`102948283.4`|`6.6`|
49+
| **FastKFunction(callBy)** |`105609306.2`|`6.8`|
50+
| **KFunction(call)** | `77096714.2`|`5.0`|
51+
| **KFunction(callBy)** | `15519730.2`|`1` |
5252

5353
![ConstructorBenchmarkResultGraph.png](./pictures/ConstructorBenchmarkResultGraph.png)
5454

55-
*This is the score I got on a `Ryzen7 3700X` in a `Windows 10` environment, with [3b8687](https://github.com/ProjectMapK/FastKFunction/tree/3b8687da712319a49e4f58a38edbb016cc0c41b7) committed.
55+
_This score was measured with `Ryzen7 3700X`, `Windows10`, [3b8687](https://github.com/ProjectMapK/FastKFunction/tree/3b8687da712319a49e4f58a38edbb016cc0c41b7) committed code and benchmark settings._
56+
_It is currently a little faster with small improvements._
5657

5758
### Raw data, and other comparisons
5859
You can get full benchmark score and some other graphs [here](https://docs.google.com/spreadsheets/d/1DJhf8KX1-BAxCGor5cZdlO3626AZbKeet-rkk26XGAE/).
5960

6061
### Mechanism
62+
`FastKFunction` realizes high speed by the following ingenuity.
63+
64+
- Call `KFunction` with `call` if the argument is fully initialized.
65+
- If possible, call `Java` `Method` or `Constructor` directly for further speedup.
66+
- Efficient retention of arguments and switching between `call`/`callBy` calls by devising a data structure.
67+
- Avoid using `spread operator` as much as possible.
68+
6169
I have a blog post on the mechanism of fast invocation (in Japanese).
6270

6371
- [【Kotlin】KFunctionを高速に呼び出す(前編) \- Qiita](https://qiita.com/wrongwrong/items/f7b15d54956191f471d1)
6472
- [【Kotlin】KFunctionを高速に呼び出す(後編) \- Qiita](https://qiita.com/wrongwrong/items/fe75bae3911eff319e68)
6573

6674
### Benchmarking
6775
You can run the benchmark with the `./gradlew jmh`.
68-
Please note that it will take about 5 hours in total if executed with the default settings.
76+
It takes about 45 minutes to run a complete benchmark.
6977

7078
```bash
7179
./gradlew jmh
@@ -78,46 +86,30 @@ Please see here for the introduction method.
7886

7987
- [ProjectMapK / FastKFunction](https://jitpack.io/#ProjectMapK/FastKFunction)
8088

81-
## How to use FastKFunction.
89+
## How to use FastKFunction
8290

83-
### Instance parameter.
84-
If you call an instance function, you can expect a faster call with `instance parameter`.
85-
86-
```kotlin
87-
data class Sample(
88-
val arg1: Int,
89-
val arg2: Int
90-
) {
91-
fun instanceFun(arg3: Int): Int = arg1 + arg2 + arg3
92-
}
91+
### Initialization
92+
In some cases, `instance parameter` is required to initialize `FastKFunction`.
93+
Even if the `instance parameter` is not required, passing it may speed up the process.
9394

94-
val sample = Sample(1, 2)
95+
The following is the correspondence table.
9596

96-
val fastKFunction = FastKFunction.of(sample::instanceFun, sample)
97-
```
97+
| | instance parameter | description |
98+
|:-----------------------------------:|:------------------:|------------------------------------------------------------|
99+
| **Constructor** | Unnecessary | |
100+
| **Top level function** | Unnecessary | |
101+
| **Method reference from instance** | Optional | Passing the `instance parameter` will speed up the call. |
102+
| **Function defined for the object** | Optional | Passing `instance parameter` will speed up initialization. |
103+
| **Top level extension function** | Required | |
104+
| **Method reference from class** | Required | |
98105

99-
Depending on how you get the `KFunction`, the `instance parameter` may be required.
100-
Even if the `instance parameter` is not required, passing an `instance parameter` will make the call faster.
106+
Calling the `constructor` of an `inner class` or an `extension function` defined in an `instance` is currently not supported.
101107

102-
### How to call.
108+
### How to call
103109
`FastKFunction` supports two major types of calls.
104110

105-
#### Call by vararg or Collection.
106-
Calling with `vararg` or `Collection` is faster if you don't need to use the default arguments and
107-
can get them in the order in which they are defined.
108-
109-
```kotlin
110-
val fastKFunction: FastKFunction<Sample> = FastKFunction.of(function)
111-
112-
// call by vararg
113-
val result: Sample = fastKFunction.call(1, 2, 3, 4, 5)
114-
115-
// call by Collection
116-
val result: Sample = fastKFunction.callByCollection(listOf(1, 2, 3, 4, 5))
117-
```
118-
119-
#### Call by ArgumentBucket.
120-
If the default argument is expected to be used, a call using `ArgumentBucket` is available.
111+
#### Call by ArgumentBucket
112+
If the `default argument` is expected to be used, a call using `ArgumentBucket` is available.
121113

122114
`ArgumentBucket` has interfaces like `MutableMap<KParameter, Any?>`, which can be used, for example, as follows.
123115

@@ -140,7 +132,21 @@ fun map(src: Map<String, Any?>): Sample {
140132
}
141133
```
142134

143-
### For functions that can be called from a single argument.
135+
#### Call by vararg or Collection
136+
Calling with `vararg` or `Collection` is faster if you don't need to use the `default arguments` and
137+
can get them in the order in which they are defined.
138+
139+
```kotlin
140+
val fastKFunction: FastKFunction<Sample> = FastKFunction.of(function)
141+
142+
// call by vararg
143+
val result: Sample = fastKFunction.call(1, 2, 3, 4, 5)
144+
145+
// call by Collection
146+
val result: Sample = fastKFunction.callByCollection(listOf(1, 2, 3, 4, 5))
147+
```
148+
149+
### For functions that can be called from a single argument
144150
For a function that can be called with a single argument, you can use the `SingleArgFastKFunction`.
145151

146152
```kotlin

0 commit comments

Comments
 (0)