What a fast local loop can do?
hilltracer opened this issue · comments
Introduction
The purpose of this document is to show what speed up we can have when optimizing operations with local variables in rholang.
This work related with two documents:
Now each sending and receiving operation in Rholang is saved in the eventLog:
But for data processing, we can avoid local operations, as shown below.
But we need to learn how to detect local operations. This question is open.
Why need to avoid saving local values in the eventLog?
Because it's slow. We need to spend time for:
- Serializing;
- Hashing;
- Sorting;
- Refunding (We must refund the full cost for matched com events);
Also we need spend time and disc space to save in BlockStore and sending to the validators.
We can optimize the operations in the reducer (see the red and green entries in the picture below). But it still won't do much good for data processing.
Experimental results
Performance tests:
b5285b7
1 optimization step: removing serialization from charging:
93e416a
2 optimization step for Int: remove substituting and evaluating from List
No change
2 optimization step for List: remove substituting and evaluating from List
29f5c8c
2 optimization step for Map: optimization of Map
29f5c8c
3 optimization step: remove looping from eventLog
44ef594
Sum of Ints
for( @n, @x <= @"loop" ) {
match (n == 0) {
true => @"$outcomeCh"!(x)
false => @"loop"!((n - 1), x + n)
}
}
Num | Init | 1 step: removing serialization from charging | 3 step: remove looping from eventLog |
---|---|---|---|
100 | 882 | 839 | 369 |
200 | 999 | 927 | 437 |
300 | 1046 | 924 | 286 |
400 | 1026 | 937 | 277 |
500 | 1338 | 1219 | 253 |
600 | 1281 | 1304 | 296 |
700 | 1325 | 1147 | 212 |
800 | 1461 | 1129 | 223 |
900 | 1561 | 1213 | 245 |
1000 | 1578 | 1297 | 256 |
1100 | 1757 | 1437 | 280 |
1200 | 1833 | 1441 | 311 |
1300 | 2001 | 1540 | 325 |
1400 | 2190 | 1636 | 346 |
1500 | 2318 | 1805 | 372 |
1600 | 2575 | 1987 | 418 |
1700 | 2618 | 2088 | 391 |
1800 | 2740 | 2225 | 401 |
1900 | 2805 | 2334 | 463 |
2000 | 2957 | 2423 | 468 |
Append in List
@"loop"!($numberElements, []) |
for( @n, @x <= @"loop" ) {
match (n == 0) {
true => @"$outcomeCh"!(x)
false => @"loop"!((n - 1), x ++ [1])
}
}
Num | Init | 1 step: removing serialization from charging | 2 step: remove substituting and evaluating from List | 3 step: remove looping from eventLog |
---|---|---|---|---|
100 | 1220 | 1316 | 923 | 401 |
200 | 1985 | 2521 | 1358 | 583 |
300 | 3443 | 3384 | 2387 | 420 |
400 | 6669 | 5889 | 3386 | 295 |
500 | 9898 | 8340 | 5115 | 261 |
600 | 13218 | 11495 | 7171 | 432 |
700 | 16926 | 15465 | 9649 | 250 |
800 | 22879 | 21679 | 11392 | 276 |
900 | 27612 | 28086 | 14510 | 311 |
1000 | 32345 | 35621 | 16901 | 327 |
Append in Map
@"loop"!($numberElements, {}) |
for( @n, @x <= @"loop" ) {
match (n == 0) {
true => @"$outcomeCh"!(x)
false => @"loop"!((n - 1), x.set(n,n))
}
}
Num | Init | 1 step: removing serialization from charging | 2 step: optimization of Map | 3 step: remove looping from eventLog |
---|---|---|---|---|
100 | 3489 | 3006 | 1692 | 604 |
200 | 10377 | 9264 | 3660 | 558 |
300 | 24632 | 19869 | 6896 | 479 |
400 | 46370 | 35158 | 11343 | 429 |
500 | 67139 | 54624 | 17394 | 463 |
600 | 107936 | 78667 | 24792 | 546 |
Conclusions
If we want Rholang to be used for data processing, we must optimize the work with local variables. Otherwise, it is justified to use Rholang as an intermediate layer between the user program and storage.