Set 15000 of blocks for more than 1 min by MNS

Discussion in 'Plugin Development' started by Jbody, Dec 22, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Jbody

    Hi everyone! I start use NMS (net.minecraft.server) calls for block generation in the world, as advised respected desht here https://forums.bukkit.org/threads/massive-block-changes.73988/ , here https://forums.bukkit.org/threads/generating-a-circle-without-lag.100573/ , and here https://forums.bukkit.org/threads/massive-block-changes.73988/ , but get mystically result, more than 1 min set time for about 15 000 blocks of 4 hollow spheres.
    i try make it by difference ways - by Bukkit's block.setType(), by MBU (https://github.com/desht/buster/blob/master/src/main/java/me/desht/buster/MassBlockUpdate.java), by buster example (https://github.com/desht/buster/blob/master/src/main/java/me/desht/buster/buster.java) (thanx desht!) and by direct for chunk.a way.

    part of direct for chunk.a code here is:
    Code:java
    1. private int[] sblockp = {89,1,1};
    2. private void drawSphereFromCashe(){
    3. log.info(" Cache Created! " + cacheSphereX.size());
    4. log.info(" Creating Sphere..");
    5. World world = Bukkit.getServer().getWorld("world");
    6. net.minecraft.server.v1_4_5.World w = ((CraftWorld) world).getHandle();
    7. for(int i = 1; i <= cacheSphereX.size(); i++)
    8. {
    9. net.minecraft.server.v1_4_5.Chunk chunk = w.getChunkAt(cacheSphereX.get(i) >> 4, cacheSphereZ.get(i) >> 4);
    10. chunk.a(cacheSphereX.get(i) & 15, cacheSphereY.get(i), cacheSphereZ.get(i) & 15, sblockp[new Random().nextInt(sblockp.length)], (byte)0);
    11. }
    12. log.info(" Sphere Created!");
    13. }

    sphere block coordinates prepared into TreeMap arrays in advance, and computation this coords in block setting process is no need

    result in world:
    [​IMG]
    as u can see, all fine! perfect result!
    except one thing.....

    next screen shot of log show time generation. this is work of NMS chunk.a directly way. R - radius, XXXX numbers - amount blocks for set sphere.
    sphere with radius 15 block gen time is 8 seconds,
    sphere with radius 22 block gen time is 25 seconds,
    set time for all 4 spheres (about 15 000 blocks) by directly way (code at top) - more than 1 min!! (1:05)
    this not a Bukkit's block.setType() way!!
    (MBU MNS, buster example, or directly to chunk MNS, but this one generated by part of code at top):
    [​IMG]
    of course, during the setting blocks server is stop responding

    in green - just TreeMap - read cycle test with comments out chunk.a procedure
    and with assigning values ​​to unused variables. takes no time.
    best result! 0 sec! honestly, i thought that's should work NMS way. but no sphere without any sets :(
    [​IMG]

    and for for compare, in red - Bukkit's block.setType() set times, about 1:35
    [​IMG]

    dev system have 64bit OS, craftbukkit v 1.4.5 server, java 7, 8 gb Ram, SSD drive.
    the difference between NMS and bukkit block.setType() is very trivial, why?
    how generate more thousands blocks per sec with MNS ?
    i missed anything important in the MNS generation?
     
  2. Offline

    NathanWolf

    Wow, science!

    8 seconds seems way too long for a 15 block radius sphere, but that is just a reaction. I'm pretty sure I can do a lot more than that, not using NMS.

    I had looked at desht's performance comparisons, it seemed like NMS was a big improvement for very large changes, but the difference was minimal for smaller changes like what you're doing.

    I'm afraid I can't see why this would be slow, but when I get a chance I can do my own timing tests for comparison, if you want. I currently process 1000 blocks per tick to avoid server lag, which means the server can easily handle 20k blocks per second without any noticeable lag... So our numbers do not match up.

    Oh, and before it gets brought up again... I do a lot of creating big spheres up in the air, so I don't think this is some specific "building above air" issue.

    That said, are you doing this in a real world, or like a big empty plane?
     
  3. Offline

    Jbody

    thanx) desht use NMS calls in the issue, in fact, here is not a many choices for set block:
    1: Bukkit's block.setType()
    2: direct call to the chunk (NMS)
    3: 1 or 2. can add more options if I'm wrong )))
    i did, as do all for MNS, but my result not seems like as NMS.... therefore i created this thread

    the fact that, i don't use any calculations for set block unit in my code by any way, bukkit set or MNS.
    coordinate values taking directly from array for set block by NMS, in my example, what code may be faster?
    i'm so confused


    i'm use usually bukkit world, test server not have many plugins, if i remove all plug-ins except test plugin, the result will not change
    [​IMG]
    i tried set stone block for square 100*100*100 by this code, i tried generate different structures in different worlds, and in empty world (multiworld plugin) also, set time is not changed. why NMS is slow for me....

    for all:
    can be at this moment somebody make something like that, please post here successful fast work result of your generate by NMS calls


    Upd. im tested this clean code:
    Code:java
    1. package nms;
    2.  
    3. import static net.minecraft.server.v1_4_5.MinecraftServer.log;
    4. import org.bukkit.Bukkit;
    5. import org.bukkit.ChatColor;
    6. import org.bukkit.World;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.craftbukkit.v1_4_5.CraftWorld;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.plugin.java.JavaPlugin;
    12.  
    13. public class NMS extends JavaPlugin {
    14.  
    15. int mode = 1;
    16.  
    17. @Override
    18. public void onEnable() {
    19. log.info("* NMS TEST *");
    20. }
    21.  
    22. public void start() {
    23. World world = Bukkit.getServer().getWorld("world");
    24. net.minecraft.server.v1_4_5.World w = ((CraftWorld) world).getHandle();
    25. if (mode == 1) {
    26. log.info(" * Starting NMS Fill");
    27. }
    28. if (mode == 2) {
    29. log.info(" * Starting Bukkit Fill");
    30. }
    31. if (mode == 3) {
    32. log.info(" * Clean Fill");
    33. }
    34. //filling 100*100*100 square (1000000 blocks)
    35. for (int x = -50; x <= 50; x++) {
    36. for (int y = 100; y <= 200; y++) {
    37. for (int z = -50; z <= 50; z++) {
    38. if (mode == 1) {
    39. net.minecraft.server.v1_4_5.Chunk chunk = w.getChunkAt(x >> 4, z >> 4);
    40. chunk.a(x & 15, y, z & 15, 1, (byte) 0);
    41. }
    42. if (mode == 2) {
    43. world.getBlockAt(x, y, z).setTypeId(1);
    44. }
    45. if (mode == 3) {
    46. net.minecraft.server.v1_4_5.Chunk chunk = w.getChunkAt(x >> 4, z >> 4);
    47. chunk.a(x & 15, y, z & 15, 0, (byte) 0);
    48. }
    49. }
    50. }
    51. }
    52. log.info(" Filled!!!");
    53. }
    54.  
    55. @Override
    56. public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String args[]) {
    57. Player player = (Player) sender;
    58.  
    59. if (cmd.getName().equalsIgnoreCase("nms")) {
    60. player.sendMessage(ChatColor.GOLD + " * Fill now!");
    61.  
    62. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    63. public void run() {
    64. mode = 1;
    65. start();
    66. }
    67. }, 0L);
    68.  
    69. return true;
    70. }
    71. if (cmd.getName().equalsIgnoreCase("bukkit")) {
    72. player.sendMessage(ChatColor.GOLD + " * Fill now!");
    73.  
    74. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    75. public void run() {
    76. mode = 2;
    77. start();
    78. }
    79. }, 0L);
    80.  
    81. return true;
    82. }
    83. if (cmd.getName().equalsIgnoreCase("cc")) {
    84. player.sendMessage(ChatColor.GOLD + " * Clean now!");
    85.  
    86. Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
    87. public void run() {
    88. mode = 3;
    89. start();
    90. }
    91. }, 0L);
    92.  
    93. return true;
    94. }
    95. return false;
    96. }
    97. }
    98.  


    and got 30 sec for NMS calls:
    Code:
    04:27:25 [INFO]  * Starting NMS Fill
    04:27:55 [INFO]  Filled!!!
    and 16 sec for NMS clean (set 1000000 air blocks):
    Code:
    04:28:22 [INFO]  * Clean Fill
    04:28:38 [INFO]  Filled!!!
    and 50 sec for Bukkit setTypeId(1):
    Code:
    04:28:58 [INFO]  * Starting Bukkit Fill
    04:29:48 [INFO]  Filled!!!
    and 18 sec for Bukkit clean (setTypeId(Air)):
    Code:
    04:39:32 [INFO]  * Clean Fill
    04:39:50 [INFO]  Filled!!!
    picture the same
    we can see just higher performance for NMS way - in all causes NMS for about 30% higher than the Bakkit setBlock, but, it is not a revolution in the block generation...
     
Thread Status:
Not open for further replies.

Share This Page