Change ipairs() back to pairs() #1311
Labels
No Label
#P1 CRITICAL
#P2: HIGH
#P3: elevated
#P4 priority: medium
#P6: low
#Review
annoying
API
bug
code quality
combat
commands
compatibility
configurability
contribution inside
controls
core feature
creative mode
delayed for engine release
documentation
duplicate
enhancement
environment
feature request
gameplay
graphics
ground content conflict
GUI/HUD
help wanted
incomplete feature
invalid / won't fix
items
looking for contributor
mapgen
meta
mineclone2+
Minecraft >= 1.13
Minecraft >= 1.17
missing feature
mobile
mobs
mod support
model needed
multiplayer
Needs adoption
needs discussion
needs engine change
needs more information
needs research
nodes
non-mob entities
performance
player
possible close
redstone
release notes
schematics
Skyblock
sounds
Testing / Retest
tools
translation
unconfirmed
mcl5
mcla
Media missing
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: VoxeLibre/VoxeLibre#1311
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
@AFCMS I've written a test to check your latest optimization (see below).
It seems for me that
ipairs()
works at least 22 times slower thanpairs()
.So please please undo latest changes ASAP.
Maybe it's one of the reasons of MineClone2/MineClone2#1283 as well.
I've already mentioned it here MineClone2/MineClone2#1146 (comment)
I would suggest better open new issues before doing any mass optimizations because it affects all the code and should be planned because of that.
(see code block below)
Good you took the time to measure this :)
It makes sense for
pairs
to be faster because it is a less strict version ofipairs
. It is for example valid forpairs
to be eqvivalent toipairs
when using only numeric keys and that is most efficient (indices are stored in numerical order). The reverse does not hold true becauseipairs
needs to iterate over the keys in a deterministic order.I also think you put the CRITICAL label when you meant to put high priority. Among the labels CRITICAL is described as "for crashes, catastrophic bugs" while high priority is described as "for the most important issues".
@kay27 ??????????????????
I don't understand.
And I got:
Pairs: 137000
Ipairs: 57000
for i =.... : 75000
@kay27 Can lua version affect pairs/ipairs time of execution?
For me:
Thanks for pointing me.
Yep, it was kinda a panic because some functions with iterations call other functions from these iterations and these callee contain iterations as well so I think it might cause logarithmic slowdown.
But as I currently not absolutely sure in this I'll better have removed the label
If these changes really affects performances, I will be happy to change them back
on_joinplayer means for me that this function calls only once when somebody joins the server
this is a special moment on the timeline, where the server becomes a little more busy than usual to store new connection in memory, make initial calculations, etc
so i wouldn't better measure at this time at all
please check my test code, i might be wrong too
but common practise of making lua work faster seems to be
using pairs stillooops, sorry, of course accessing using integer indexes infor
loops (but i need to check if it suitable for objects like these) andpairs
takes 2nd placeUSING pairs still (see below).
There are some reasons your results could be different. The second iteration where you use
ipairs
could have better cache utilization because it has repeated the same iteration withpairs
once before.It could also be the case that
ipairs
is faster thanpairs
depending on the ways arrays were created. If the{ 1, 2, 3, 4 }
notation is used Lua could maybe optimize the key layout soipairs
could be faster.You also generally want to avoid doing I/O like
print
in loops when performing benchmarks (unless you want to measure the time it takes to print too).I think kay27's benchmark is probably more accurate to real scenarios because it uses
minetest.get_objects_inside_radius
.@kay27 After trying the test from https://springrts.com/wiki/Lua_Performance#TEST_9:_for-loops, it seems that it takes a litle less time with pairs() than with ipairs(). And after trying your code, pairs seems insanely more powerfull than ipairs.
Also, what about
for i = 1, #<table>
?Try this benchmark instead. It is the same but with different arrays to minimize the effect of caching
Then I get
@ryvnf I got:
It is pretty different from your results.
I think
ipairs
should be preferred for code readability unless the code is performance critical. Most of the time it will not matter.Also note that
pairs
is different fromipairs
and#
because it will also go through non-numeric keys.@AFCMS That is suprising.
Could you also try to swap the order of the
pairs
andipairs
loop? (to see if there is still some caching going on there)I did multiple tests about 1 minute apart.
Ipairs looks quite consistent, with the exception of test 7.
This test uses print() which maybe depends on outer
irrlichtfreetype so for me it's more likely yet another random noise generator :)And why don't you like my test? :)
I've taken additional steps to make equal measurements. Also I've added the linear for, but still not sure if it works as expected.
The idea of the test is: you move, and enumerate the objects around you. So the more objects you have around you - the better result you get.
And the time divides by the number of object to make it always fair.
And seems the docs (and I) were wrong about
linear for
.And there is an easy way to check if my test is right - just swap
pairs
andipairs
in first two functions - and you should get some comparable mixed averaged results for them - let's see:Test code works like a charm, I confirm that.
Linear for
works better here because pairs and ipairs are mixed and the result is average result of them both.We always should better use
paris
instead ofipairs
expect maybe the cases we need to reindex the table.Final test code (sorry for the size, I've added it to the end of
mods\ENVIRONMENT\mcl_weather\weather_core.lua
afterload_weather()
, you're free to find better place):@kay27 I got that with your code but I don't understand the result:
EDIT: Also, pairs() is different from paris() xD
Please add/meet some objects around you, eg. spawn some harmless mobs.
The result is: all the time divided by the number of measurements equals average time per operation in microseconds.
But 25, 24 and 29 are too small values to get perfect result, more objects will help getting it more accurate
Will try soon.
@kay27
Is there enough mobs? :-)
Result:
It seems pairs is clearly superior to ipairs....
I will change all back
Fixed!
Not sure if here were enough mobs around you because I've forgotten to say that they should be at maximum distance of 25 nodes for this test. But even the approximate result you've got seems to be correct.
Limit of 25 has some reasons, related to map chunks. But it can be increased in every of 6 function
FYI:
You can use
git revert <COMMIT>
to revert some commit.There are now several places with
pairs
where previously more likely wasiparis
and key variable is meaningful, it's not underscore, moreover, it is used further sometimes:I hope it will be all right with this code.
But of course it would be better to check.
Did you see the screenshot?
@AFCMS Change ipairs() back to pairs()to Change ipairs() back to pairs()