Solved The lag of YML file is real!

Discussion in 'Plugin Development' started by Cheesepro, Dec 5, 2014.

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

    Cheesepro

    Currently my server was lagging like crazy so I decide to run a timing exam, and this is what it has...
    Code:
      Pct Total    Pct Tick      Total          Avg    PerTick        Count        Event
          4.98%    460.50%      0.23 s      230.25 ms    0.0          0.0k        Playerloc::onPlayerTP(PlayerTeleportEvent)
    I was shocked.. 460%!!! and here is the part of code it was lagging about:
    Code:java
    1. @EventHandler
    2. public void onPlayerTP(PlayerTeleportEvent e){
    3. Player p = e.getPlayer();
    4. String pn = p.getName();
    5. int x = e.getPlayer().getLocation().getBlockX();
    6. int y = e.getPlayer().getLocation().getBlockY();
    7. int z = e.getPlayer().getLocation().getBlockZ();
    8. float pitch = e.getPlayer().getLocation().getPitch();
    9. float yaw = e.getPlayer().getLocation().getYaw();
    10. String w = e.getPlayer().getLocation().getWorld().getName().toString();
    11. settings.getData().set(pn + ".previousloc.pitch", Float.valueOf(pitch));
    12. settings.getData().set(pn + ".previousloc.yaw", Float.valueOf(yaw));
    13. settings.getData().set(pn + ".previousloc.X", Integer.valueOf(x));
    14. settings.getData().set(pn + ".previousloc.Y", Integer.valueOf(y));
    15. settings.getData().set(pn + ".previousloc.Z", Integer.valueOf(z));
    16. settings.getData().set(pn + ".previousloc.W", w);
    17. settings.saveData();
    18. }

    What the code was doing is whenever a player teleports, it will record the location of the player, in order for /back to work... So I don't know if there is any other less lag ways of saving the data instead of using .yml (Please don't say database... I know nothing about it xD)

    If you do know a way, please help me Thank you :D
     
  2. Offline

    Skionz

    Cheesepro Use Maps. Saving data to the disk or a database is a bad idea.
     
    Cheesepro likes this.
  3. Offline

    Cheesepro

    Skionz do you mean hashmaps? so is it like saved the data to the memory?
     
  4. Offline

    Skionz

    Cheesepro It doesn't matter which type of map unless you want to order the data.
     
    Cheesepro likes this.
  5. Offline

    WesJD

    Cheesepro
    If you can, only save the data when really needed(login/logout) through a Map.

    Code:java
    1. Map<String> thisIsAMap = new HashMap<String>();
     
    Cheesepro likes this.
  6. Offline

    Cheesepro

    Skionz Ok Thank you, I was wonder if your API will work fine for this :D, since I looked at it, and it seems to have Map options, oh and is there a .jar download to your API? Cause I kinda like it :D

    WesJD Thanks :D
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 29, 2016
  7. Offline

    mythbusterma

    Cheesepro

    The point being, the issue is caused by you doing File I/O every time that block of code is being executed, which is very slow.
     
  8. Offline

    blablubbabc

    Cheesepro

    The configuration already is only a wrapped map. So the real issue is not setting stuff inside the configuration, but (re)loading and saving it frequently. So instead of saving the configuration after each change you could set some flag and only save every few minutes and on disable, maybe even asynchronous.
    Though 230ms at average for one save still seems long to me.. so could you show us your code which gets called for settings.getData()? Maybe you are constantly reloading the configuratiom from file there..

    Also, not related to the config but still an improvement: instead of calling e.getPlayer().getLocation(), and creating new Location objects, 6 times you could call it only once (Location loc = e.getPlayer().getLocation(); ) and then use 'loc' the other times.
     
    Cheesepro likes this.
  9. Offline

    ferrybig

    Try reducing the duplicate calls to methods, they create some lagg, examples how the code can be improved for performance:

    1. Remove repeated calls to Player.getLocation() as its makes a new copy every time:
    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerTP(PlayerTeleportEvent e){
    4. Player p = e.getPlayer();
    5. String pn = p.getName();
    6. Location loc = p.getLocation();
    7. int x = loc.getBlockX();
    8. int y = loc.getBlockY();
    9. int z = loc.getBlockZ();
    10. float pitch = loc.getPitch();
    11. float yaw = loc.getYaw();
    12. String w = loc.getWorld().getName().toString();
    13. settings.getData().set(pn + ".previousloc.pitch", Float.valueOf(pitch));
    14. settings.getData().set(pn + ".previousloc.yaw", Float.valueOf(yaw));
    15. settings.getData().set(pn + ".previousloc.X", Integer.valueOf(x));
    16. settings.getData().set(pn + ".previousloc.Y", Integer.valueOf(y));
    17. settings.getData().set(pn + ".previousloc.Z", Integer.valueOf(z));
    18. settings.getData().set(pn + ".previousloc.W", w);
    19. settings.saveData();
    20. }
    21.  


    2. Remove duplicate calls to settings.getData()

    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerTP(PlayerTeleportEvent e){
    4. Player p = e.getPlayer();
    5. String pn = p.getName();
    6. Location loc = p.getLocation();
    7. int x = loc.getBlockX();
    8. int y = loc.getBlockY();
    9. int z = loc.getBlockZ();
    10. float pitch = loc.getPitch();
    11. float yaw = loc.getYaw();
    12. String w = loc.getWorld().getName().toString();
    13. ConfigurationSection sec = settings.getData(); // Data may return a other type here, we don't know the source
    14. sec .set(pn + ".previousloc.pitch", Float.valueOf(pitch));
    15. sec .set(pn + ".previousloc.yaw", Float.valueOf(yaw));
    16. sec .set(pn + ".previousloc.X", Integer.valueOf(x));
    17. sec .set(pn + ".previousloc.Y", Integer.valueOf(y));
    18. sec .set(pn + ".previousloc.Z", Integer.valueOf(z));
    19. sec .set(pn + ".previousloc.W", w);
    20. settings.saveData();
    21. }
    22.  



    Remove unneeded calls to Number.valueof() and String.toString()

    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerTP(PlayerTeleportEvent e){
    4. Player p = e.getPlayer();
    5. String pn = p.getName();
    6. Location loc = p.getLocation();
    7. int x = loc.getBlockX();
    8. int y = loc.getBlockY();
    9. int z = loc.getBlockZ();
    10. float pitch = loc.getPitch();
    11. float yaw = loc.getYaw();
    12. String w = loc.getWorld().getName();
    13. ConfigurationSection sec = settings.getData(); // Data may return a other type here, we don't know the source
    14. sec .set(pn + ".previousloc.pitch", pitch);
    15. sec .set(pn + ".previousloc.yaw", yaw);
    16. sec .set(pn + ".previousloc.X", x);
    17. sec .set(pn + ".previousloc.Y", y);
    18. sec .set(pn + ".previousloc.Z", z);
    19. sec .set(pn + ".previousloc.W", w);
    20. settings.saveData();
    21. }
    22.  



    Don't go to deep inside the configuration every time, the inefficiency of splitting the config makes lagg

    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerTP(PlayerTeleportEvent e){
    4. Player p = e.getPlayer();
    5. String pn = p.getName();
    6. Location loc = p.getLocation();
    7. int x = loc.getBlockX();
    8. int y = loc.getBlockY();
    9. int z = loc.getBlockZ();
    10. float pitch = loc.getPitch();
    11. float yaw = loc.getYaw();
    12. String w = loc.getWorld().getName();
    13. ConfigurationSection sec = settings.getData(); // Data may return a other type here, we don't know the source
    14. ConfigurationSection previousloc = sec.getConfigurationSection(pn + ".previousloc");
    15. if(previousloc == null) previousloc = sec.createSection(pn + ".previousloc");
    16. previousloc .set("pitch", pitch);
    17. previousloc .set("yaw", yaw);
    18. previousloc .set("X", x);
    19. previousloc .set("Y", y);
    20. previousloc .set("Z", z);
    21. previousloc .set("W", w);
    22. settings.saveData(); // Maybe delayed saving o the file can improve the lagg, but this requires a link to the plugin instance, with isn't existing inside the example code
    23. }
    24.  



    After doing al those steps, lagg should be less. I cannot measure how much the lagg would be removed, since you didn't post a full SSCCE
     
    Cheesepro likes this.
  10. Offline

    mythbusterma

    ferrybig

    Except.....none of that is it all the issue.

    The only issue is the settings.saveData() line.
     
    Cheesepro likes this.
  11. Offline

    Cheesepro

Thread Status:
Not open for further replies.

Share This Page