MySQL region support calls toLowerCase() repeatedly needlessly for polygons
LadyCailinBot opened this issue ยท 2 comments
WORLDGUARD-2255 - Reported by Gildan27
When WorldGuard is configured to use MySQL, saving a large ProtectedPolygonalRegion has very poor performance, and can crash a server. This was observed with a ProtectedPolygonalRegion consisting of a high number of points (10,000 or so). It works fine with regions.yml.
Thread: http://forum.sk89q.com/threads/performance-problems-with-mysql.9033/
In MySQLDatabase.java, on line 947 (https://github.com/sk89q/worldguard/blob/master/src/main/java/com/sk89q/worldguard/protection/databases/MySQLDatabase.java#L947), a call is made to String.toLowerCase() in a for loop. This can cause a performance issue, as String.toLowerCase() creates a new copy of the same string each time the code loops (see the last paragraph of http://etutorials.org/Programming/Java+performance+tuning/Chapter+5.+Strings/5.5+String+Comparisons+and+Searches).
I demonstrate a test case in the thread above (permalink: http://forum.sk89q.com/threads/performance-problems-with-mysql.9033/#post-15445), that reduces execution time of some test code by 350% by assigning the string outside of the for loop once, then referencing that (instead of calling String.toLowerCase each time the code loops).
Thus, changing lines 945-947 in MySQLDatabase.java to be something like the following should result in a major performance increase for MySQL configurations:
String idLowerCase = region.getId().toLowerCase();
for (BlockVector2D point : region.getPoints()) {
insertPoly2dPointStatement.setString(1, idLowerCase);
...
There may be other places in the MySQL code where similar optimizations can be made.
Comment by sk89q
Unless you use a binary collation, case sensitivity doesn't even matter in MySQL too. The MySQL portion of regions is so bad; not sure why we added it so easily.
Either way, I am going to keep it lower case.
Comment by sk89q
Fixed.
34fa5ec