From d656e2b433bb3726ed89e4953d250dc525818ca0 Mon Sep 17 00:00:00 2001 From: orbiter Date: Fri, 28 Oct 2005 01:22:11 +0000 Subject: [PATCH] added a memory-profile chart generation to database performance testing git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@993 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- source/dbtest.java | 52 +++++++ source/de/anomic/plasma/plasmaGrafics.java | 6 +- source/de/anomic/tools/ImageChart.java | 169 +++++++++++++++++++++ source/de/anomic/tools/ImagePainter.java | 84 ++++++---- 4 files changed, 280 insertions(+), 31 deletions(-) create mode 100644 source/de/anomic/tools/ImageChart.java diff --git a/source/dbtest.java b/source/dbtest.java index d5330609d..30796063b 100644 --- a/source/dbtest.java +++ b/source/dbtest.java @@ -9,10 +9,12 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Random; +import java.util.Date; import de.anomic.server.serverCodings; import de.anomic.kelondro.kelondroIndex; import de.anomic.kelondro.kelondroTree; +import de.anomic.tools.ImageChart; public class dbtest { @@ -33,6 +35,8 @@ public class dbtest { } public static void main(String[] args) { + System.setProperty("java.awt.headless", "true"); + String dbe = args[0]; // the database engine String command = args[1]; // test command String tablename = args[2]; // name of test-table @@ -40,6 +44,9 @@ public class dbtest { long startup = System.currentTimeMillis(); try { kelondroIndex table = null; + // create a memory profiler + memprofiler profiler = new memprofiler(1024, 320, 120, new File(tablename + ".profile.png")); + profiler.start(); // create the database access if (dbe.equals("kelondro")) { @@ -89,6 +96,7 @@ public class dbtest { long afterclose = System.currentTimeMillis(); System.out.println("Execution time: open=" + (afterinit - startup) + ", command=" + (aftercommand - afterinit) + ", close=" + (afterclose - aftercommand) + ", total=" + (afterclose - startup)); + profiler.terminate(); } catch (Exception e) { e.printStackTrace(); } @@ -203,3 +211,47 @@ final class dbTable implements kelondroIndex { } } + +final class memprofiler extends Thread { + + ImageChart memChart; + boolean run; + File outputFile; + long start; + + public memprofiler(int width, int height, int expectedTimeSeconds, File outputFile) { + this.outputFile = outputFile; + int expectedKilobytes = (int) 20 * 1024;//(Runtime.getRuntime().totalMemory() / 1024); + memChart = new ImageChart(width, height, "000010", 50, 20, 20, 20, "MEMORY CHART FROM EXECUTION AT " + new Date()); + int timescale = 10; // steps with each 10 seconds + int memscale = 1024; + memChart.declareDimension(ImageChart.DIMENSION_BOTTOM, timescale, (width - 40) * timescale / expectedTimeSeconds, "FFFFFF", "555555", "SECONDS"); + memChart.declareDimension(ImageChart.DIMENSION_LEFT, memscale, (height - 40) * memscale / expectedKilobytes , "FFFFFF", "555555", "KILOBYTES"); + run = true; + start = System.currentTimeMillis(); + } + + public void run() { + int seconds0 = 0, kilobytes0 = 0; + int seconds1 = 0, kilobytes1 = 0; + while(run) { + memChart.setColor("FF0000"); + seconds1 = (int) ((System.currentTimeMillis() - start) / 1000); + kilobytes1 = (int) (Runtime.getRuntime().freeMemory() / 1024); + memChart.chartLine(ImageChart.DIMENSION_BOTTOM, ImageChart.DIMENSION_LEFT, seconds0, kilobytes0, seconds1, kilobytes1); + seconds0 = seconds1; + kilobytes0 = kilobytes1; + try {Thread.sleep(200);} catch (InterruptedException e) {} + } + try { + memChart.toPNG(true, outputFile); + } catch (IOException e) {} + } + + public void terminate() { + run = false; + while (this.isAlive()) { + try {Thread.sleep(1000);} catch (InterruptedException e) {} + } + } +} \ No newline at end of file diff --git a/source/de/anomic/plasma/plasmaGrafics.java b/source/de/anomic/plasma/plasmaGrafics.java index bcae46481..c0b66c442 100644 --- a/source/de/anomic/plasma/plasmaGrafics.java +++ b/source/de/anomic/plasma/plasmaGrafics.java @@ -183,9 +183,9 @@ public class plasmaGrafics { // draw description networkPicture.setColor("FFFFFF"); networkPicture.setMode(ImagePainter.MODE_ADD); - networkPicture.print(2, 8, "THE YACY NETWORK", true); - networkPicture.print(2, 16, "DRAWING OF " + totalCount + " SELECTED PEERS", true); - networkPicture.print(width - 2, 8, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), false); + networkPicture.print(2, 8, 0, "THE YACY NETWORK", true); + networkPicture.print(2, 16, 0, "DRAWING OF " + totalCount + " SELECTED PEERS", true); + networkPicture.print(width - 2, 8, 0, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), false); // set timestamp networkPictureDate = System.currentTimeMillis(); diff --git a/source/de/anomic/tools/ImageChart.java b/source/de/anomic/tools/ImageChart.java new file mode 100644 index 000000000..8b278976a --- /dev/null +++ b/source/de/anomic/tools/ImageChart.java @@ -0,0 +1,169 @@ +// ImageChart.java +// --------------------------- +// (C) by Michael Peter Christen; mc@anomic.de +// first published on http://www.anomic.de +// Frankfurt, Germany, 2005 +// created: 26.10.2005 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Using this software in any meaning (reading, learning, copying, compiling, +// running) means that you agree that the Author(s) is (are) not responsible +// for cost, loss of data or any harm that may be caused directly or indirectly +// by usage of this softare or this documentation. The usage of this software +// is on your own risk. The installation and usage (starting/running) of this +// software may allow other people or application to access your computer and +// any attached devices and is highly dependent on the configuration of the +// software which must be done by the user of the software; the author(s) is +// (are) also not responsible for proper configuration and usage of the +// software, even if provoked by documentation provided together with +// the software. +// +// Any changes to this file according to the GPL as documented in the file +// gpl.txt aside this file in the shipment you received can be done to the +// lines that follows this copyright notice here, but changes must not be +// done inside the copyright notive above. A re-distribution must contain +// the intact and unchanged copyright notice. +// Contributions and changes to the program code must be marked as such. + + +package de.anomic.tools; + +import java.io.File; +import java.io.IOException; + +public class ImageChart extends ImagePainter { + + public static final int DIMENSION_RIGHT = 0; + public static final int DIMENSION_TOP = 1; + public static final int DIMENSION_LEFT = 2; + public static final int DIMENSION_BOTTOM = 3; + + int leftborder; + int rightborder; + int topborder; + int bottomborder; + int[] scales = new int[]{0,0,0,0}; + int[] pixels = new int[]{0,0,0,0}; + String[] colnames = new String[]{"FFFFFF","FFFFFF","FFFFFF","FFFFFF"}; + String[] colscale = new String[]{null,null,null,null}; + String[] tablenames = new String[]{"","","",""}; + + public ImageChart(int width, int height, String backgroundColor, + int leftborder, int rightborder, int topborder, int bottomborder, + String name) { + super(width, height, backgroundColor); + this.leftborder = leftborder; + this.rightborder = rightborder; + this.topborder = topborder; + this.bottomborder = bottomborder; + if (name != null) { + print(width / 2 - name.length() * 3, 6, 0, name, true); + } + } + + public void declareDimension(int dimensionType, int scale, int pixelperscale, String colorNaming, String colorScale, String name) { + if ((dimensionType == DIMENSION_LEFT) || (dimensionType == DIMENSION_RIGHT)) { + drawVerticalScale((dimensionType == DIMENSION_LEFT), scale, pixelperscale, colorNaming, colorScale, name); + } + if ((dimensionType == DIMENSION_TOP) || (dimensionType == DIMENSION_BOTTOM)) { + drawHorizontalScale((dimensionType == DIMENSION_TOP), scale, pixelperscale, colorNaming, colorScale, name); + } + scales[dimensionType] = scale; + pixels[dimensionType] = pixelperscale; + colnames[dimensionType] = colorNaming; + colscale[dimensionType] = colorScale; + tablenames[dimensionType] = name; + } + + public void chartDot(int dimension_x, int dimension_y, int coord_x, int coord_y, int dotsize) { + int x = coord_x * pixels[dimension_x] / scales[dimension_x]; + int y = coord_y * pixels[dimension_y] / scales[dimension_y]; + if (dotsize == 1) plot(leftborder + x, height - bottomborder - y); + else dot(leftborder + x, height - bottomborder - y, dotsize, true); + } + + public void chartLine(int dimension_x, int dimension_y, int coord_x1, int coord_y1, int coord_x2, int coord_y2) { + int x1 = coord_x1 * pixels[dimension_x] / scales[dimension_x]; + int y1 = coord_y1 * pixels[dimension_y] / scales[dimension_y]; + int x2 = coord_x2 * pixels[dimension_x] / scales[dimension_x]; + int y2 = coord_y2 * pixels[dimension_y] / scales[dimension_y]; + line(leftborder + x1, height - bottomborder - y1, leftborder + x2, height - bottomborder - y2); + } + + private void drawHorizontalScale(boolean top, int scale, int pixelperscale, String colorNaming, String colorScale, String name) { + int y = (top) ? topborder : height - bottomborder; + int x = leftborder; + int s = 0; + while (x < width - rightborder) { + if ((colorScale != null) && (x > leftborder) && (x < (width - rightborder))) { + setColor(colorScale); + line(x, topborder, x, height - bottomborder); + } + setColor(colorNaming); + line(x, y - 3, x, y + 3); + print(x, (top) ? y - 3 : y + 9, 0, Integer.toString(s), true); + x += pixelperscale; + s += scale; + } + setColor(colorNaming); + print(width - rightborder, (top) ? y - 9 : y + 15, 0, name, false); + line(leftborder - 4, y, width - rightborder + 4, y); + } + + private void drawVerticalScale(boolean left, int scale, int pixelperscale, String colorNaming, String colorScale, String name) { + int x = (left) ? leftborder : width - rightborder; + int y = height - bottomborder; + int s = 0; + String s1; + int s1max = 0; + while (y > topborder) { + if ((colorScale != null) && (y > topborder) && (y < (height - bottomborder))) { + setColor(colorScale); + line(leftborder, y, width - rightborder, y); + } + setColor(colorNaming); + line(x - 3, y, x + 3, y); + s1 = Integer.toString(s); + if (s1.length() > s1max) s1max = s1.length(); + print((left) ? leftborder - 4 : width - rightborder + 4, y, 0, s1, (!left)); + y -= pixelperscale; + s += scale; + } + setColor(colorNaming); + print((left) ? x - s1max * 6 - 6 : x + s1max * 6 + 9, topborder, 90, name, false); + line(x, topborder - 4, x, height - bottomborder + 4); + } + + public static void main(String[] args) { + System.setProperty("java.awt.headless", "true"); + ImageChart ip = new ImageChart(640, 480, "000010", 40, 40, 20, 20, "TESTCHART"); + ip.declareDimension(DIMENSION_BOTTOM, 10, 30, "FFFFFF", "555555", "time"); + ip.declareDimension(DIMENSION_TOP, 10, 40, "FFFFFF", null, "count"); + ip.declareDimension(DIMENSION_LEFT, 100, 30, "FFFFFF", "555555", "money"); + ip.declareDimension(DIMENSION_RIGHT, 100, 50, "FFFFFF", null, "stock"); + ip.setColor("FF0000"); + ip.chartDot(DIMENSION_BOTTOM, DIMENSION_LEFT, 20, 100, 5); + ip.chartLine(DIMENSION_BOTTOM, DIMENSION_LEFT, 20, 100, 50, 200); + //ip.print(100, 100, 0, "TEXT", true); + //ip.print(100, 100, 0, "1234", false); + //ip.print(100, 100, 90, "TEXT", true); + //ip.print(100, 100, 90, "1234", false); + try { + ip.toPNG(true, new File("/Users/admin/dev/yacy/trunk/testimage.png")); + } catch (IOException e) {} + } + +} diff --git a/source/de/anomic/tools/ImagePainter.java b/source/de/anomic/tools/ImagePainter.java index 8d41e6b55..17e27480e 100644 --- a/source/de/anomic/tools/ImagePainter.java +++ b/source/de/anomic/tools/ImagePainter.java @@ -2,8 +2,8 @@ // --------------------------- // (C) by Michael Peter Christen; mc@anomic.de // first published on http://www.anomic.de -// Frankfurt, Germany, 2004 -// last major change: 16.09.2004 +// Frankfurt, Germany, 2005 +// last major change: 16.09.2005 // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -47,6 +47,7 @@ package de.anomic.tools; +import java.io.File; import java.awt.Graphics2D; import java.awt.GraphicsEnvironment; import java.awt.GraphicsDevice; @@ -57,6 +58,8 @@ import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.util.HashSet; import java.util.ArrayList; +import javax.imageio.ImageIO; +import java.io.IOException; public class ImagePainter implements Cloneable { @@ -93,10 +96,10 @@ public class ImagePainter implements Cloneable { private static int[][] circles = new int[0][]; + protected int width, height; private byte[] grid; // one-dimensional arrays are much faster than two-dimensional - private int width, height; - private int defaultColR, defaultColG, defaultColB; - private byte defaultMode; + private int defaultColR, defaultColG, defaultColB; + private byte defaultMode; public ImagePainter(int width, int height, String backgroundColor) { this(width, height, colNum(backgroundColor)); @@ -165,7 +168,7 @@ public class ImagePainter implements Cloneable { this.defaultMode = m; } - private void plot(int x, int y) { + protected void plot(int x, int y) { if ((x < 0) || (x >= width)) return; if ((y < 0) || (y >= height)) return; int n = 3 * (x + y * width); @@ -191,7 +194,7 @@ public class ImagePainter implements Cloneable { } - private void line(int Ax, int Ay, int Bx, int By) { + protected void line(int Ax, int Ay, int Bx, int By) { // Bresenham's line drawing algorithm int dX = Math.abs(Bx-Ax); int dY = Math.abs(By-Ay); @@ -331,22 +334,6 @@ public class ImagePainter implements Cloneable { } } - private void print(int x, int y, char letter) { - int index = (int) letter - 0x20; - if (index >= font.length) return; - long character = font[index]; - long row; - for (int i = 0; i < 5; i++) { - row = character & 0x1f; - character = character >> 5; - for (int j = 0; j < 5; j++) { - if ((row & 1) == 1) plot(x + 5 - j, y); - row = row >> 1; - } - y--; - } - } - public void dot(int x, int y, int radius, boolean filled) { if (filled) { for (int r = radius; r >= 0; r--) circle(x, y, r); @@ -360,11 +347,44 @@ public class ImagePainter implements Cloneable { } - public void print(int x, int y, String message, boolean alignRight) { - int xx = (alignRight) ? x : x - 6 * message.length(); + private void print(int x, int y, int angle, char letter) { + int index = (int) letter - 0x20; + if (index >= font.length) return; + long character = font[index]; + long row; + for (int i = 0; i < 5; i++) { + row = character & 0x1f; + character = character >> 5; + if (angle == 0) { + for (int j = 0; j < 5; j++) { + if ((row & 1) == 1) plot(x + 5 - j, y); + row = row >> 1; + } + y--; + } + if (angle == 90) { + for (int j = 0; j < 5; j++) { + if ((row & 1) == 1) plot(x, y - 5 + j); + row = row >> 1; + } + x--; + } + } + } + + public void print(int x, int y, int angle, String message, boolean alignLeft) { + int xx = 0, yy = 0; + if (angle == 0) { + xx = (alignLeft) ? x : x - 6 * message.length(); + yy = y; + } else if (angle == 90) { + xx = x; + yy = (alignLeft) ? y : y + 6 * message.length(); + } for (int i = 0; i < message.length(); i++) { - print(xx, y, message.charAt(i)); - xx += 6; + print(xx, yy, angle, message.charAt(i)); + if (angle == 0) xx += 6; + else if (angle == 90) yy -= 6; } } @@ -380,7 +400,7 @@ public class ImagePainter implements Cloneable { int xp = x - 3 * message.length(); if ((angle > (90 + arcDist)) && (angle < (270 - arcDist))) xp = x - 6 * message.length(); if ((angle < (90 - arcDist)) || (angle > (270 + arcDist))) xp = x; - print(xp, yp, message, true); + print(xp, yp, 0, message, true); } public void arcLine(int cx, int cy, int innerRadius, int outerRadius, int angle) { @@ -402,6 +422,7 @@ public class ImagePainter implements Cloneable { int y = cy - (int) (arcRadius * Math.sin(Math.PI * angle / 180)); arc(x, y, innerRadius, outerRadius, fromArc, toArc); } + public BufferedImage toImage(boolean complementary) { /* @@ -462,5 +483,12 @@ public class ImagePainter implements Cloneable { return new BufferedImage(0, 0, BufferedImage.TYPE_INT_RGB); } } + + public void toPNG(boolean complementary, File f) throws IOException { + BufferedImage bi = toImage(complementary); + ImageIO.write(bi, "png", f); + } + + }