package de.mrbesen.youtubecrawler; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; public class Profiler { private final List sectionList = Lists.newArrayList(); private final List timestampList = Lists.newArrayList(); /** Flag profiling enabled */ public boolean profilingEnabled; /** Current profiling section */ private String profilingSection = ""; private final Map profilingMap = Maps.newHashMap(); private long start = -1; /** * Clear profiling. */ public void clearProfiling() { this.profilingMap.clear(); this.profilingSection = ""; this.sectionList.clear(); start = -1; } /** * Start section */ public void startSection(String name) { if (this.profilingEnabled) { if(start == -1) start = System.nanoTime(); if (this.profilingSection.length() > 0) { this.profilingSection = this.profilingSection + "."; } this.profilingSection = this.profilingSection + name; this.sectionList.add(this.profilingSection); this.timestampList.add(Long.valueOf(System.nanoTime())); //System.out.println("started section: " + name + " currently in: " + profilingSection); } } /** * End section */ public void endSection() { if (this.profilingEnabled) { try { long start = System.nanoTime(); long stop = ((Long) this.timestampList.remove(this.timestampList.size() - 1)).longValue(); this.sectionList.remove(this.sectionList.size() - 1); long delta = start - stop; if (this.profilingMap.containsKey(this.profilingSection)) { this.profilingMap.put(this.profilingSection, Long.valueOf(((Long) this.profilingMap.get(this.profilingSection)).longValue() + delta)); } else { this.profilingMap.put(this.profilingSection, Long.valueOf(delta)); } this.profilingSection = this.sectionList.isEmpty() ? "" : (String) this.sectionList.get(this.sectionList.size() - 1); } catch (Exception e ) { e.printStackTrace(); } } } private int sectioncount(String profilername) { int count = 1; for(char c : profilername.toCharArray()) { if(c == '.') count ++; } return count; } public List getProfilingData(String profilerName) { if (this.profilingEnabled) { List out = Lists.newArrayList(); long totaltime = System.nanoTime() - start; //calculate percentage of each child section int count = sectioncount(profilerName); for (String prfiler_name : this.profilingMap.keySet()) { if (prfiler_name.startsWith(profilerName) && sectioncount(prfiler_name) == count+1) { long subsectiontime = ((Long) this.profilingMap.get(prfiler_name)).longValue(); double totaltimep = (double) subsectiontime * 100.0D / (double) totaltime; out.add(new Profiler.Result(prfiler_name, totaltimep, subsectiontime)); } } for (String key : this.profilingMap.keySet()) { this.profilingMap.put(key, Long.valueOf(((Long) this.profilingMap.get(key)).longValue() * 999L / 1000L)); } return out; } else { return Collections.emptyList(); } } public LinkedList getTreeView() { return getTreeView("root", ""); } private LinkedList getTreeView(String name, String leading) { LinkedList out = new LinkedList<>(); if(new Exception().getStackTrace().length > 50)//prevent stack overflow debug only return out; for(Result res : getProfilingData(name)) { out.add(leading + res.profilerName + " " + (res.time/10000000)/100D + "s " + form(res.totalUsePercentage) + "% "); out.addAll(getTreeView(res.profilerName, leading + "\t")); } return out; } private String form(double d) { return (((long) (d*1000))/1000)+""; } /** * End current section and start a new section */ public void endStartSection(String name) { this.endSection(); this.startSection(name); } public String getNameOfLastSection() { return this.sectionList.size() == 0 ? "[UNKNOWN]" : (String) this.sectionList.get(this.sectionList.size() - 1); } public static final class Result { public double totalUsePercentage; public String profilerName; public long time; public Result(String profilerName, double totalUsePercentage, long time) { this.profilerName = profilerName; this.totalUsePercentage = totalUsePercentage; this.time = time; } } }