Haven-King / Atmosfera

A mod for Minecraft that adds atmospheric sounds
Apache License 2.0
26 stars 9 forks source link

Boost performance by reducing the update frequency #31

Open Qendolin opened 2 years ago

Qendolin commented 2 years ago

Atmosfera causes quite a hit on performance due to constant memory allocation and hash map merging. This could easily be improved by reducing the update frequency (specifically of atmosfera$updateEnvironmentContext) since the environment does not change so quickly. It would be nice to have an option for the amount of ticks between each update. I.e.: A slider from 1 to 100 with a default value of 10.

Maybe 10 ticks / update is still to much, 20 ticks could be more than enough.

Qendolin commented 2 years ago

This could be implemented like this:

public class AtmosphericSoundHandler {
    private int tick;

    private void tickSounds() {
//      ClientWorld world = MinecraftClient.getInstance().world;

//      if (world != null) {
//          SoundManager soundManager = MinecraftClient.getInstance().getSoundManager();

            if(tick % AtmosferaConfig.getUpdateInterval() == 0) {
                ((ClientWorldDuck) world).atmosfera$updateEnvironmentContext();
            }

//          for (AtmosphericSound definition : this.sounds) {
//              if (!this.soundInstances.containsKey(definition) || this.soundInstances.get(definition).isDone()) {
//                  float volume = definition.getVolume(world);
//
//                  // The non-zero volume prevents the events getting triggered multiple times at volumes near zero.
//                  if (volume >= 0.0125 && MinecraftClient.getInstance().options.getSoundVolume(SoundCategory.AMBIENT) > 0) {
//                      AtmosphericSoundInstance soundInstance = new AtmosphericSoundInstance(definition, 0.0001F);
//                      this.soundInstances.put(definition, soundInstance);
//                      soundManager.playNextTick(soundInstance);
//                      Atmosfera.debug("volume > 0: {} - {}", definition.id(), volume);
//                  }
//              }
//          }
//      }
//
//      this.soundInstances.values().removeIf(AtmosphericSoundInstance::isDone);
        tick++;
    }

And a few additions to AtmosferaConfig:

...

private static int UPDATE_INTERVAL = 20;

private static void read() {
    ...

    if(json.has("misc")) {
        JsonObject misc = json.getAsJsonObject("misc");
        if (misc.has("update_interval")) {
        UPDATE_INTERVAL = misc.get("update_interval").getAsInt();
        }
    }

    ...
}

private static void write() {
    ...

    JsonObject misc = new JsonObject();
    misc.addProperty("update_interval", UPDATE_INTERVAL);
    jsonObject.add("misc", misc);

    ...
}

public static Screen getScreen(Screen parent) {
    ...

    ConfigCategory miscCategory = builder.getOrCreateCategory(new TranslatableText("config.category.atmosfera.misc"));
    miscCategory.addEntry(builder.entryBuilder().startIntSlider(
        new TranslatableText("config.value.atmosfera.update_interval"), UPDATE_INTERVAL, 1, 100)
        .setSaveConsumer(integer -> UPDATE_INTERVAL = integer)
        .setDefaultValue(20)
        .build()
    );

    ...
}

public static int getUpdateInterval() {
    return UPDATE_INTERVAL;
}