001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020package org.apache.isis.core.runtime.profiler; 021 022import java.text.NumberFormat; 023import java.util.HashMap; 024import java.util.Locale; 025import java.util.Map; 026 027public class Profiler { 028 029 private final static String DELIMITER = "\t"; 030 private static NumberFormat FLOAT_FORMAT = NumberFormat.getNumberInstance(Locale.UK); 031 private static NumberFormat INTEGER_FORMAT = NumberFormat.getNumberInstance(Locale.UK); 032 033 private final static Map<Thread, String> threads = new HashMap<Thread, String>(); 034 035 private static int nextId = 0; 036 private static int nextThread = 0; 037 038 protected static ProfilerSystem profilerSystem = new ProfilerSystem(); 039 040 /** 041 * Primarily for testing. 042 * 043 * @param profilerSystem 044 */ 045 public static void setProfilerSystem(final ProfilerSystem profilerSystem) { 046 Profiler.profilerSystem = profilerSystem; 047 } 048 049 public static String memoryLog() { 050 final long free = memory(); 051 return INTEGER_FORMAT.format(free) + " bytes"; 052 } 053 054 private static long time() { 055 return profilerSystem.time(); 056 } 057 058 private static long memory() { 059 return profilerSystem.memory(); 060 } 061 062 // //////////////////////////////////////////////////////////// 063 // Profiler instance, constructor 064 // //////////////////////////////////////////////////////////// 065 066 private final String thread; 067 068 private final int id; 069 private final String name; 070 071 private long elapsedTime = 0; 072 private long memory; 073 private long start = 0; 074 private boolean timing = false; 075 076 public Profiler(final String name) { 077 this.name = name; 078 synchronized (Profiler.class) { 079 this.id = nextId++; 080 } 081 final Thread t = Thread.currentThread(); 082 final String thread = threads.get(t); 083 if (thread != null) { 084 this.thread = thread; 085 } else { 086 this.thread = "t" + nextThread++; 087 threads.put(t, this.thread); 088 } 089 memory = memory(); 090 } 091 092 public String getName() { 093 return name; 094 } 095 096 // //////////////////////////////////////////////////////////// 097 // start, stop, reset 098 // //////////////////////////////////////////////////////////// 099 100 public void reset() { 101 elapsedTime = 0; 102 start = time(); 103 memory = memory(); 104 } 105 106 public void start() { 107 start = time(); 108 timing = true; 109 } 110 111 public void stop() { 112 timing = false; 113 final long end = time(); 114 elapsedTime += end - start; 115 } 116 117 // //////////////////////////////////////////////////////////// 118 // MemoryUsage, ElapsedTime 119 // //////////////////////////////////////////////////////////// 120 121 public long getElapsedTime() { 122 return timing ? time() - start : elapsedTime; 123 } 124 125 public long getMemoryUsage() { 126 return memory() - memory; 127 } 128 129 // //////////////////////////////////////////////////////////// 130 // logging 131 // //////////////////////////////////////////////////////////// 132 133 public String memoryUsageLog() { 134 return INTEGER_FORMAT.format(getMemoryUsage()) + " bytes"; 135 } 136 137 public String timeLog() { 138 return FLOAT_FORMAT.format(getElapsedTime() / 1000.0) + " secs"; 139 } 140 141 public String log() { 142 return id + DELIMITER + thread + DELIMITER + getName() + DELIMITER + getMemoryUsage() + DELIMITER + getElapsedTime(); 143 } 144 145 @Override 146 public String toString() { 147 return getElapsedTime() + "ms - " + name; 148 } 149 150}