From 032a77dac00ca4ec98a7af3f16d7f99191727d60 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Wed, 30 May 2018 01:09:15 -0500 Subject: Branch to add in better debug output from GT cpu load. ns instead of ms. --- .../api/metatileentity/BaseMetaTileEntity.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java') diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index d44ada526f..609a35bfae 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -277,7 +277,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE } mRunningThroughTick = true; - long tTime = System.currentTimeMillis(); + long tTime = System.nanoTime(); int tCode = 0; boolean aSideServer = isServerSide(); boolean aSideClient = isClientSide(); @@ -573,11 +573,11 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE } if (aSideServer && hasValidMetaTileEntity()) { - tTime = System.currentTimeMillis() - tTime; + tTime = System.nanoTime() - tTime; if (mTimeStatistics.length > 0) mTimeStatistics[mTimeStatisticsIndex = (mTimeStatisticsIndex + 1) % mTimeStatistics.length] = (int) tTime; - if (tTime > 0 && tTime > GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) - System.out.println("WARNING: Possible Lag Source at [" + xCoord + ", " + yCoord + ", " + zCoord + "] in Dimension " + worldObj.provider.dimensionId + " with " + tTime + "ms caused by an instance of " + getMetaTileEntity().getClass()); + if (tTime > 0 && tTime > (GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING*1000000) && mTickTimer > 1000 && getMetaTileEntity().doTickProfilingMessageDuringThisTick() && mLagWarningCount++ < 10) + System.out.println("WARNING: Possible Lag Source at [" + xCoord + ", " + yCoord + ", " + zCoord + "] in Dimension " + worldObj.provider.dimensionId + " with " + tTime + "ns caused by an instance of " + getMetaTileEntity().getClass()); } mWorkUpdate = mInventoryChanged = mRunningThroughTick = false; @@ -706,8 +706,14 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE if (aLogLevel > 1) { if (mTimeStatistics.length > 0) { double tAverageTime = 0; - for (int tTime : mTimeStatistics) tAverageTime += tTime; - tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ms since " + mTimeStatistics.length + " ticks."); + double tWorstTime = 0; + for (int tTime : mTimeStatistics) { + tAverageTime += tTime; + if (tTime > tWorstTime) { + tWorstTime = tTime; + } + } + tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns since " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); } if (mLagWarningCount > 0) { tList.add("Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); -- cgit From fe08b96bd94a487a2e26654b1812691a91bd3407 Mon Sep 17 00:00:00 2001 From: Richard Hendricks Date: Sat, 2 Jun 2018 03:05:39 -0500 Subject: For the first 6 ticks after pushing, always push. Then goto every 5 ticks. Should work OK for any machine. For higher output performance, use larger output stack size. Uses item ID numbers instead of strings to sort, much faster. Resolves https://github.com/GTNewHorizons/NewHorizons/issues/3006 --- .../api/metatileentity/BaseMetaTileEntity.java | 4 +- .../automation/GT_MetaTileEntity_ChestBuffer.java | 333 ++++++++++----------- 2 files changed, 161 insertions(+), 176 deletions(-) (limited to 'src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java') diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java index 609a35bfae..95f3416a00 100644 --- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java @@ -712,8 +712,10 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE if (tTime > tWorstTime) { tWorstTime = tTime; } + // Uncomment this line to print out tick-by-tick times. + //tList.add("tTime " + tTime); } - tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns since " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); + tList.add("Average CPU-load of ~" + (tAverageTime / mTimeStatistics.length) + "ns over " + mTimeStatistics.length + " ticks with worst time of " + tWorstTime + "ns."); } if (mLagWarningCount > 0) { tList.add("Caused " + (mLagWarningCount >= 10 ? "more than 10" : mLagWarningCount) + " Lag Spike Warnings (anything taking longer than " + GregTech_API.MILLISECOND_THRESHOLD_UNTIL_LAG_WARNING + "ms) on the Server."); diff --git a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java index 99a360ad11..e73631cd93 100644 --- a/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java +++ b/src/main/java/gregtech/common/tileentities/automation/GT_MetaTileEntity_ChestBuffer.java @@ -1,175 +1,158 @@ -package gregtech.common.tileentities.automation; - -import gregtech.api.enums.Textures; -import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; -import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; -import gregtech.api.objects.GT_RenderedTexture; -import gregtech.api.util.GT_Utility; -import gregtech.common.gui.GT_Container_ChestBuffer; -import gregtech.common.gui.GT_GUIContainer_ChestBuffer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; - -import java.util.Arrays; -import java.util.Comparator; - -public class GT_MetaTileEntity_ChestBuffer - extends GT_MetaTileEntity_Buffer { - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { - super(aID, aName, aNameRegional, aTier, 28, new String[]{ - "Buffers up to 27 Item Stacks", - "Use Screwdriver to regulate output stack size", - "Consumes 3EU per moved Item"}); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { - super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { - super(aName, aTier, aInvSlotCount, aDescription, aTextures); - } - - public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { - return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); - } - - public ITexture getOverlayIcon() { - return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); - } - - public boolean isValidSlot(int aIndex) { - return aIndex < this.mInventory.length - 1; - } - - protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { - if(aBaseMetaTileEntity.hasInventoryBeenModified()) { - fillStacksIntoFirstSlots(); - } - // mSuccess will be negative if the call is caused by the %200 aTimer. Otherwise it will be positive, and only every other tick is a push attempted. - if ( (mSuccess <= 0 ) || (( mSuccess > 0 ) && ( (mSuccess % 2) == 0 )) ){ - super.moveItems(aBaseMetaTileEntity, aTimer); - } - // mSuccesss is set to 50 on a successful move - if(mSuccess == 50) { - fillStacksIntoFirstSlots(); - } - if(mSuccess < 0) { - mSuccess = 0; - } - } - -// Implementation using Java built in sort algorithm -// Uses terribad string comparison to sort against. Would be better if we did something else? - protected void sortStacks() { - Arrays.sort(this.mInventory, new Comparator() { - @Override - // Taken from https://gist.github.com/Choonster/876acc3217229e172e46 - public int compare(ItemStack o1, ItemStack o2) { - if ( o2 == null ) - return -1; - if( o1 == null ) - return 1; - Item item1 = o1.getItem(); - Item item2 = o2.getItem(); - - // If item1 is a block and item2 isn't, sort item1 before item2 - if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { - return -1; - } - - // If item2 is a block and item1 isn't, sort item1 after item2 - if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { - return 1; - } - - String displayName1 = o1.getDisplayName(); - String displayName2 = o2.getDisplayName(); - - int result = displayName1.compareToIgnoreCase(displayName2); - //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); - return result; - } - }); - } - -// Implementation of insertion sort -// Worst case time of a 2.8ms -/* - public int compare(ItemStack o1, ItemStack o2) { - if ( o2 == null ) - return -1; - if( o1 == null ) - return 1; - Item item1 = o1.getItem(); - Item item2 = o2.getItem(); - - // If item1 is a block and item2 isn't, sort item1 before item2 - if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { - return -1; - } - - // If item2 is a block and item1 isn't, sort item1 after item2 - if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { - return 1; - } - - String displayName1 = o1.getDisplayName(); - String displayName2 = o2.getDisplayName(); - - int result = displayName1.compareToIgnoreCase(displayName2); - //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); - return result; - } - - protected void sortStacks() { - int i = 1, j; - while( i < this.mInventory.length ){ - j = i; - while( (j > 0) && ( compare(this.mInventory[j-1], this.mInventory[j]) == -1) ) { - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, j-1, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - j--; - } - i++; - } - } -*/ - - protected void fillStacksIntoFirstSlots() { - sortStacks(); - // Merge small stacks together - for (int i = 0; i < this.mInventory.length-1;) { - //System.out.println( (this.mInventory[i] == null) ? "Slot empty " + i : "Slot " + i + " holds " + this.mInventory[i].getDisplayName()); - for (int j = i + 1; j < this.mInventory.length; j++) { - if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { - GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); - //System.out.println( "Moving slot " + j + " into slot " + i ); - } - else { - i=j; - break; // No more matching items for this i, do next i - } - } - } - } - - public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } - - public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { - return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); - } -} +package gregtech.common.tileentities.automation; + +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Buffer; +import gregtech.api.objects.GT_RenderedTexture; +import gregtech.api.util.GT_Utility; +import gregtech.common.gui.GT_Container_ChestBuffer; +import gregtech.common.gui.GT_GUIContainer_ChestBuffer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import java.util.Arrays; +import java.util.Comparator; + +public class GT_MetaTileEntity_ChestBuffer + extends GT_MetaTileEntity_Buffer { + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier) { + super(aID, aName, aNameRegional, aTier, 28, new String[]{ + "Buffers up to 27 Item Stacks", + "Use Screwdriver to regulate output stack size", + "Consumes 3EU per moved Item"}); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(int aID, String aName, String aNameRegional, int aTier, int aInvSlotCount, String[] aDescription) { + super(aID, aName, aNameRegional, aTier, aInvSlotCount, aDescription); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public GT_MetaTileEntity_ChestBuffer(String aName, int aTier, int aInvSlotCount, String[] aDescription, ITexture[][][] aTextures) { + super(aName, aTier, aInvSlotCount, aDescription, aTextures); + } + + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new GT_MetaTileEntity_ChestBuffer(this.mName, this.mTier, this.mInventory.length, this.mDescriptionArray, this.mTextures); + } + + public ITexture getOverlayIcon() { + return new GT_RenderedTexture(Textures.BlockIcons.AUTOMATION_CHESTBUFFER); + } + + public boolean isValidSlot(int aIndex) { + return aIndex < this.mInventory.length - 1; + } + + protected void moveItems(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + if(aBaseMetaTileEntity.hasInventoryBeenModified()) { + fillStacksIntoFirstSlots(); + } + // mSuccess will be negative if the call is caused by the %200 aTimer, always try to push. Otherwise it will be positive. + // For the first 6 ticks after a successful move (49->44), push every tick. Then go to every 5 ticks. + if ( (mSuccess <= 0 ) || (mSuccess > 43) || ((mSuccess % 5) == 0 )){ + super.moveItems(aBaseMetaTileEntity, aTimer); + } + // mSuccesss is set to 50 on a successful move + if(mSuccess == 50) { + fillStacksIntoFirstSlots(); + } + if(mSuccess < 0) { + mSuccess = 0; + } + } + +// Implementation using Java built in sort algorithm +// Uses terribad string comparison to sort against. Would be better if we did something else? + protected void sortStacks() { + Arrays.sort(this.mInventory, new Comparator() { + @Override + // Taken from https://gist.github.com/Choonster/876acc3217229e172e46 + public int compare(ItemStack o1, ItemStack o2) { + if( o2 == null ) + return -1; + if( o1 == null ) + return 1; + Item item1 = o1.getItem(); + Item item2 = o2.getItem(); + + // If item1 is a block and item2 isn't, sort item1 before item2 + if (((item1 instanceof ItemBlock)) && (!(item2 instanceof ItemBlock))) { + return -1; + } + + // If item2 is a block and item1 isn't, sort item1 after item2 + if (((item2 instanceof ItemBlock)) && (!(item1 instanceof ItemBlock))) { + return 1; + } + + // If the items are blocks, use the string comparison + if ((item1 instanceof ItemBlock)) { // only need to check one since we did the check above + String displayName1 = o1.getDisplayName(); + String displayName2 = o2.getDisplayName(); + int result = displayName1.compareToIgnoreCase(displayName2); + //System.out.println("sorter: " + displayName1 + " " + displayName2 + " " + result); + return result; + } else + { + // Not a block. Use the ID and damage to compare them. + int id1 = Item.getIdFromItem( item1 ); + int id2 = Item.getIdFromItem( item2 ); + if ( id1 < id2 ) { + return -1; + } + if ( id1 > id2 ) { + return 1; + } + // id1 must equal id2, get their damage and compare + id1 = o1.getItemDamage(); + id2 = o2.getItemDamage(); + + if ( id1 < id2 ) { + return -1; + } + if ( id1 > id2 ) { + return 1; + } + return 0; + } + } + }); + } + + protected void fillStacksIntoFirstSlots() { + sortStacks(); + // Merge small stacks together + for (int i = 0; i < this.mInventory.length-1;) { + //System.out.println( (this.mInventory[i] == null) ? "Slot empty " + i : "Slot " + i + " holds " + this.mInventory[i].getDisplayName()); + for (int j = i + 1; j < this.mInventory.length; j++) { + if ((this.mInventory[j] != null) && ((GT_Utility.areStacksEqual(this.mInventory[i], this.mInventory[j])))) { + GT_Utility.moveStackFromSlotAToSlotB(getBaseMetaTileEntity(), getBaseMetaTileEntity(), j, i, (byte) 64, (byte) 1, (byte) 64, (byte) 1); + //System.out.println( "Moving slot " + j + " into slot " + i ); + } + else { + i=j; + break; // No more matching items for this i, do next i + } + } + } + } + + public Object getServerGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_Container_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } + + public Object getClientGUI(int aID, InventoryPlayer aPlayerInventory, IGregTechTileEntity aBaseMetaTileEntity) { + return new GT_GUIContainer_ChestBuffer(aPlayerInventory, aBaseMetaTileEntity); + } +} -- cgit