    001package net.minecraft.profiler;
    002
    003import java.util.ArrayList;
    004import java.util.Collections;
    005import java.util.HashMap;
    006import java.util.Iterator;
    007import java.util.List;
    008import java.util.Map;
    009
    010public class Profiler
    011{
    012    /** List of parent sections */
    013    private final List sectionList = new ArrayList();
    014
    015    /** List of timestamps (System.nanoTime) */
    016    private final List timestampList = new ArrayList();
    017
    018    /** Flag profiling enabled */
    019    public boolean profilingEnabled = false;
    020
    021    /** Current profiling section */
    022    private String profilingSection = "";
    023
    024    /** Profiling map */
    025    private final Map profilingMap = new HashMap();
    026
    027    /**
    028     * Clear profiling.
    029     */
    030    public void clearProfiling()
    031    {
    032        this.profilingMap.clear();
    033        this.profilingSection = "";
    034        this.sectionList.clear();
    035    }
    036
    037    /**
    038     * Start section
    039     */
    040    public void startSection(String par1Str)
    041    {
    042        if (this.profilingEnabled)
    043        {
    044            if (this.profilingSection.length() > 0)
    045            {
    046                this.profilingSection = this.profilingSection + ".";
    047            }
    048
    049            this.profilingSection = this.profilingSection + par1Str;
    050            this.sectionList.add(this.profilingSection);
    051            this.timestampList.add(Long.valueOf(System.nanoTime()));
    052        }
    053    }
    054
    055    /**
    056     * End section
    057     */
    058    public void endSection()
    059    {
    060        if (this.profilingEnabled)
    061        {
    062            long i = System.nanoTime();
    063            long j = ((Long)this.timestampList.remove(this.timestampList.size() - 1)).longValue();
    064            this.sectionList.remove(this.sectionList.size() - 1);
    065            long k = i - j;
    066
    067            if (this.profilingMap.containsKey(this.profilingSection))
    068            {
    069                this.profilingMap.put(this.profilingSection, Long.valueOf(((Long)this.profilingMap.get(this.profilingSection)).longValue() + k));
    070            }
    071            else
    072            {
    073                this.profilingMap.put(this.profilingSection, Long.valueOf(k));
    074            }
    075
    076            if (k > 100000000L)
    077            {
    078                System.out.println("Something\'s taking too long! \'" + this.profilingSection + "\' took aprox " + (double)k / 1000000.0D + " ms");
    079            }
    080
    081            this.profilingSection = !this.sectionList.isEmpty() ? (String)this.sectionList.get(this.sectionList.size() - 1) : "";
    082        }
    083    }
    084
    085    /**
    086     * Get profiling data
    087     */
    088    public List getProfilingData(String par1Str)
    089    {
    090        if (!this.profilingEnabled)
    091        {
    092            return null;
    093        }
    094        else
    095        {
    096            long i = this.profilingMap.containsKey("root") ? ((Long)this.profilingMap.get("root")).longValue() : 0L;
    097            long j = this.profilingMap.containsKey(par1Str) ? ((Long)this.profilingMap.get(par1Str)).longValue() : -1L;
    098            ArrayList arraylist = new ArrayList();
    099
    100            if (par1Str.length() > 0)
    101            {
    102                par1Str = par1Str + ".";
    103            }
    104
    105            long k = 0L;
    106            Iterator iterator = this.profilingMap.keySet().iterator();
    107
    108            while (iterator.hasNext())
    109            {
    110                String s1 = (String)iterator.next();
    111
    112                if (s1.length() > par1Str.length() && s1.startsWith(par1Str) && s1.indexOf(".", par1Str.length() + 1) < 0)
    113                {
    114                    k += ((Long)this.profilingMap.get(s1)).longValue();
    115                }
    116            }
    117
    118            float f = (float)k;
    119
    120            if (k < j)
    121            {
    122                k = j;
    123            }
    124
    125            if (i < k)
    126            {
    127                i = k;
    128            }
    129
    130            Iterator iterator1 = this.profilingMap.keySet().iterator();
    131            String s2;
    132
    133            while (iterator1.hasNext())
    134            {
    135                s2 = (String)iterator1.next();
    136
    137                if (s2.length() > par1Str.length() && s2.startsWith(par1Str) && s2.indexOf(".", par1Str.length() + 1) < 0)
    138                {
    139                    long l = ((Long)this.profilingMap.get(s2)).longValue();
    140                    double d0 = (double)l * 100.0D / (double)k;
    141                    double d1 = (double)l * 100.0D / (double)i;
    142                    String s3 = s2.substring(par1Str.length());
    143                    arraylist.add(new ProfilerResult(s3, d0, d1));
    144                }
    145            }
    146
    147            iterator1 = this.profilingMap.keySet().iterator();
    148
    149            while (iterator1.hasNext())
    150            {
    151                s2 = (String)iterator1.next();
    152                this.profilingMap.put(s2, Long.valueOf(((Long)this.profilingMap.get(s2)).longValue() * 999L / 1000L));
    153            }
    154
    155            if ((float)k > f)
    156            {
    157                arraylist.add(new ProfilerResult("unspecified", (double)((float)k - f) * 100.0D / (double)k, (double)((float)k - f) * 100.0D / (double)i));
    158            }
    159
    160            Collections.sort(arraylist);
    161            arraylist.add(0, new ProfilerResult(par1Str, 100.0D, (double)k * 100.0D / (double)i));
    162            return arraylist;
    163        }
    164    }
    165
    166    /**
    167     * End current section and start a new section
    168     */
    169    public void endStartSection(String par1Str)
    170    {
    171        this.endSection();
    172        this.startSection(par1Str);
    173    }
    174
    175    public String getNameOfLastSection()
    176    {
    177        return this.sectionList.size() == 0 ? "[UNKNOWN]" : (String)this.sectionList.get(this.sectionList.size() - 1);
    178    }
    179}