mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
reduce overhead of profiler when not profiling
This commit is contained in:
@@ -18,7 +18,6 @@ import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
|
||||
@@ -51,56 +50,56 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world,
|
||||
@NotNull BiomeProvider biomeProvider,
|
||||
int chunkX, int chunkZ) {
|
||||
try(ProfileFrame ignore = platform.getProfiler().profile("chunk_base_3d")) {
|
||||
int xOrig = (chunkX << 4);
|
||||
int zOrig = (chunkZ << 4);
|
||||
|
||||
Sampler3D sampler = samplerCache.getChunk(chunkX, chunkZ, world, biomeProvider);
|
||||
|
||||
long seed = world.getSeed();
|
||||
|
||||
LazilyEvaluatedInterpolator carver = new LazilyEvaluatedInterpolator(biomeProvider,
|
||||
chunkX,
|
||||
chunkZ,
|
||||
world.getMaxHeight(),
|
||||
world.getMinHeight(),
|
||||
carverHorizontalResolution,
|
||||
carverVerticalResolution,
|
||||
seed);
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
int paletteLevel = 0;
|
||||
|
||||
int cx = xOrig + x;
|
||||
int cz = zOrig + z;
|
||||
|
||||
Biome biome = biomeProvider.getBiome(cx, cz, seed);
|
||||
|
||||
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||
|
||||
int sea = paletteInfo.seaLevel();
|
||||
Palette seaPalette = paletteInfo.ocean();
|
||||
|
||||
BlockState data;
|
||||
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
||||
if(sampler.sample(x, y, z) > 0) {
|
||||
if(carver.sample(x, y, z) <= 0) {
|
||||
data = PaletteUtil.getPalette(x, y, z, sampler, paletteInfo, paletteLevel).get(paletteLevel, cx, y, cz,
|
||||
seed);
|
||||
chunk.setBlock(x, y, z, data);
|
||||
}
|
||||
|
||||
paletteLevel++;
|
||||
} else if(y <= sea) {
|
||||
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed));
|
||||
paletteLevel = 0;
|
||||
} else {
|
||||
paletteLevel = 0;
|
||||
platform.getProfiler().push("chunk_base_3d");
|
||||
int xOrig = (chunkX << 4);
|
||||
int zOrig = (chunkZ << 4);
|
||||
|
||||
Sampler3D sampler = samplerCache.getChunk(chunkX, chunkZ, world, biomeProvider);
|
||||
|
||||
long seed = world.getSeed();
|
||||
|
||||
LazilyEvaluatedInterpolator carver = new LazilyEvaluatedInterpolator(biomeProvider,
|
||||
chunkX,
|
||||
chunkZ,
|
||||
world.getMaxHeight(),
|
||||
world.getMinHeight(),
|
||||
carverHorizontalResolution,
|
||||
carverVerticalResolution,
|
||||
seed);
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
int paletteLevel = 0;
|
||||
|
||||
int cx = xOrig + x;
|
||||
int cz = zOrig + z;
|
||||
|
||||
Biome biome = biomeProvider.getBiome(cx, cz, seed);
|
||||
|
||||
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
|
||||
|
||||
int sea = paletteInfo.seaLevel();
|
||||
Palette seaPalette = paletteInfo.ocean();
|
||||
|
||||
BlockState data;
|
||||
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
|
||||
if(sampler.sample(x, y, z) > 0) {
|
||||
if(carver.sample(x, y, z) <= 0) {
|
||||
data = PaletteUtil.getPalette(x, y, z, sampler, paletteInfo, paletteLevel).get(paletteLevel, cx, y, cz,
|
||||
seed);
|
||||
chunk.setBlock(x, y, z, data);
|
||||
}
|
||||
|
||||
paletteLevel++;
|
||||
} else if(y <= sea) {
|
||||
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed));
|
||||
paletteLevel = 0;
|
||||
} else {
|
||||
paletteLevel = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
platform.getProfiler().pop("chunk_base_3d");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
@@ -27,49 +26,52 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String profile;
|
||||
|
||||
public FeatureGenerationStage(Platform platform, String id) {
|
||||
this.platform = platform;
|
||||
this.id = id;
|
||||
this.profile = "feature_stage:" + id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public void populate(ProtoWorld world) {
|
||||
try(ProfileFrame ignore = platform.getProfiler().profile("feature_stage:" + id)) {
|
||||
int cx = world.centerChunkX() << 4;
|
||||
int cz = world.centerChunkZ() << 4;
|
||||
long seed = world.getSeed();
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
int tx = cx + x;
|
||||
int tz = cz + z;
|
||||
Column<WritableWorld> column = world.column(tx, tz);
|
||||
long coordinateSeed = (seed * 31 + tx) * 31 + tz;
|
||||
|
||||
world.getBiomeProvider()
|
||||
.getBiome(tx, tz, seed)
|
||||
.getContext()
|
||||
.get(BiomeFeatures.class)
|
||||
.getFeatures()
|
||||
.getOrDefault(this, Collections.emptyList())
|
||||
.forEach(feature -> {
|
||||
try(ProfileFrame ignored = platform.getProfiler().profile(feature.getID())) {
|
||||
if(feature.getDistributor().matches(tx, tz, seed)) {
|
||||
feature.getLocator()
|
||||
.getSuitableCoordinates(column)
|
||||
.forEach(y ->
|
||||
feature.getStructure(world, tx, y, tz)
|
||||
.generate(Vector3Int.of(tx, y, tz),
|
||||
world,
|
||||
new Random(coordinateSeed * 31 + y),
|
||||
Rotation.NONE)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
platform.getProfiler().push(profile);
|
||||
int cx = world.centerChunkX() << 4;
|
||||
int cz = world.centerChunkZ() << 4;
|
||||
long seed = world.getSeed();
|
||||
for(int x = 0; x < 16; x++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
int tx = cx + x;
|
||||
int tz = cz + z;
|
||||
Column<WritableWorld> column = world.column(tx, tz);
|
||||
long coordinateSeed = (seed * 31 + tx) * 31 + tz;
|
||||
|
||||
world.getBiomeProvider()
|
||||
.getBiome(tx, tz, seed)
|
||||
.getContext()
|
||||
.get(BiomeFeatures.class)
|
||||
.getFeatures()
|
||||
.getOrDefault(this, Collections.emptyList())
|
||||
.forEach(feature -> {
|
||||
platform.getProfiler().push(feature.getID());
|
||||
if(feature.getDistributor().matches(tx, tz, seed)) {
|
||||
feature.getLocator()
|
||||
.getSuitableCoordinates(column)
|
||||
.forEach(y ->
|
||||
feature.getStructure(world, tx, y, tz)
|
||||
.generate(Vector3Int.of(tx, y, tz),
|
||||
world,
|
||||
new Random(coordinateSeed * 31 + y),
|
||||
Rotation.NONE)
|
||||
);
|
||||
}
|
||||
platform.getProfiler().pop(feature.getID());
|
||||
});
|
||||
}
|
||||
}
|
||||
platform.getProfiler().pop(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.dfsek.terra.addons.terrascript.script.builders.UnaryNumberFunctionBui
|
||||
import com.dfsek.terra.addons.terrascript.script.builders.UnaryStringFunctionBuilder;
|
||||
import com.dfsek.terra.addons.terrascript.script.builders.ZeroArgFunctionBuilder;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
import com.dfsek.terra.api.registry.key.Keyed;
|
||||
import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||
@@ -54,6 +53,8 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class);
|
||||
private final Block block;
|
||||
private final RegistryKey id;
|
||||
|
||||
private final String profile;
|
||||
private final Platform platform;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -67,7 +68,8 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.id = id;
|
||||
|
||||
this.profile = "terrascript_direct:" + id;
|
||||
|
||||
//noinspection unchecked
|
||||
functionRegistry.forEach((key, function) -> parser.registerFunction(key.getID(), function)); // Register registry functions.
|
||||
|
||||
@@ -129,15 +131,17 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) {
|
||||
return applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0));
|
||||
}
|
||||
platform.getProfiler().push(profile);
|
||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0));
|
||||
platform.getProfiler().pop(profile);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation, int recursions) {
|
||||
try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) {
|
||||
return applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions));
|
||||
}
|
||||
platform.getProfiler().push(profile);
|
||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions));
|
||||
platform.getProfiler().pop(profile);
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean applyBlock(TerraImplementationArguments arguments) {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 Polyhedral Development
|
||||
*
|
||||
* The Terra API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the common/api directory.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.api.profiler;
|
||||
|
||||
public class ProfileFrame implements AutoCloseable {
|
||||
private final Runnable action;
|
||||
|
||||
public ProfileFrame(Runnable action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
@@ -36,21 +36,6 @@ public interface Profiler {
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Return a {@link AutoCloseable} implementation that
|
||||
* may be used in a try-with-resources statement for
|
||||
* more intuitive profiling, with auto-push/pop.
|
||||
*
|
||||
* @param frame ID of frame.
|
||||
*
|
||||
* @return {@link AutoCloseable} implementation for use
|
||||
* in try-with-resources.
|
||||
*/
|
||||
default ProfileFrame profile(String frame) {
|
||||
push(frame);
|
||||
return new ProfileFrame(() -> pop(frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the profiler data.
|
||||
*/
|
||||
|
||||
@@ -51,38 +51,42 @@ public class ProfilerImpl implements Profiler {
|
||||
|
||||
@Override
|
||||
public void push(String frame) {
|
||||
STACK_SIZE.get().increment();
|
||||
if(running && SAFE.get()) {
|
||||
Stack<Frame> stack = THREAD_STACK.get();
|
||||
stack.push(new Frame(stack.isEmpty() ? frame : stack.peek().getId() + "." + frame));
|
||||
if(running) {
|
||||
STACK_SIZE.get().increment();
|
||||
if(SAFE.get()) {
|
||||
Stack<Frame> stack = THREAD_STACK.get();
|
||||
stack.push(new Frame(stack.isEmpty() ? frame : stack.peek().getId() + "." + frame));
|
||||
} else SAFE.set(false);
|
||||
} else SAFE.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pop(String frame) {
|
||||
MutableInteger size = STACK_SIZE.get();
|
||||
size.decrement();
|
||||
if(running && SAFE.get()) {
|
||||
long time = System.nanoTime();
|
||||
Stack<Frame> stack = THREAD_STACK.get();
|
||||
|
||||
Map<String, List<Long>> timingsMap = TIMINGS.get();
|
||||
|
||||
if(timingsMap.isEmpty()) {
|
||||
synchronized(accessibleThreadMaps) {
|
||||
accessibleThreadMaps.add(timingsMap);
|
||||
if(running) {
|
||||
MutableInteger size = STACK_SIZE.get();
|
||||
size.decrement();
|
||||
if(SAFE.get()) {
|
||||
long time = System.nanoTime();
|
||||
Stack<Frame> stack = THREAD_STACK.get();
|
||||
|
||||
Map<String, List<Long>> timingsMap = TIMINGS.get();
|
||||
|
||||
if(timingsMap.isEmpty()) {
|
||||
synchronized(accessibleThreadMaps) {
|
||||
accessibleThreadMaps.add(timingsMap);
|
||||
}
|
||||
}
|
||||
|
||||
Frame top = stack.pop();
|
||||
if(!stack.isEmpty() ? !top.getId().endsWith("." + frame) : !top.getId().equals(frame))
|
||||
throw new MalformedStackException("Expected " + frame + ", found " + top);
|
||||
|
||||
List<Long> timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>());
|
||||
|
||||
timings.add(time - top.getStart());
|
||||
}
|
||||
|
||||
Frame top = stack.pop();
|
||||
if(!stack.isEmpty() ? !top.getId().endsWith("." + frame) : !top.getId().equals(frame))
|
||||
throw new MalformedStackException("Expected " + frame + ", found " + top);
|
||||
|
||||
List<Long> timings = timingsMap.computeIfAbsent(top.getId(), id -> new ArrayList<>());
|
||||
|
||||
timings.add(time - top.getStart());
|
||||
if(size.get() == 0) SAFE.set(true);
|
||||
}
|
||||
if(size.get() == 0) SAFE.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user