BlackBerry Forums Support Community

BlackBerry Forums Support Community (http://www.blackberryforums.com/)
-   Developer Forum (http://www.blackberryforums.com/developer-forum/)
-   -   Can the size of an application influence its speed ? (http://www.blackberryforums.com/developer-forum/143868-can-size-application-influence-its-speed.html)

pa4o85 08-06-2008 07:38 AM

Can the size of an application influence its speed ?
 
I have an application that is about 900 kb big and I have a tree field in it. The focus movement is not fast enough i.e. when I scroll the trackwheel over a custom context menu the focus does not change at the same time (immediately). When I removed the tree field (I thought the problem is in the tree field), that was in the same page where the context menu shows, then it was almost ok, but still the focus didn't change its position immediately, it is almost ok, but not like some system context menu. So I try to find where is the problem and I thought it could be be size of the application. Is there any sence ? Thanks !!!

bemshaswing 08-06-2008 09:18 AM

I find it extremely unlikely that the size of an app would be a factor in processing efficiency. Your culprit is likely elsewhere, maybe a code posting could help us out.

pa4o85 08-06-2008 09:24 AM

Well I have an application that contains about 50 .java files and I made it for my company so I don't think it is a good idea to paste a whole amount of code here. I also found it very unlikely the size to be the problem, but I just cannot find other reasons now. Maybe the number of the initialized objects to be the reason for that behaviour, but I think the garbage collector takes care for that ?

bemshaswing 08-06-2008 09:47 AM

No, I wouldn't expect you to past 900kb worth of code, but in particular the tree field might be of help.

If you think it's performance related to memory, try using the debugger's memory snapshot utility, it'll tell you whether or not you're using too much of the available memory

pa4o85 08-06-2008 10:01 AM

So, the Tree class:
Code:

public class Tree extends VerticalFieldManager implements DrawStyle {
  /** the width of the tree field */
  private int prefWidth;
  /** the height of the tree field */
  private int prefHeight;
  /** the tree field itself */
  private TreeField tree;
 
  private AccountManager accountManager;
 
  /**  */
  private int currentNode;
  /**  */
  private int currentParentNode;
 
  /**
  * Constructs a new tree field object. Each of the keys of the map represents
  * the parent nodes of the tree. The relevant values (more than one; put in
  * a List object) are the child nodes for their parents.
  *
  * @param map - Map
  * @param font - Font
  */
  public Tree(AccountManager accountManager) {
    super(Manager.NO_VERTICAL_SCROLL);
    prefWidth = Display.getWidth() - 6;
    prefHeight = Display.getHeight() - 26;
    this.accountManager = accountManager;
   
    VerticalFieldManager vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
    tree = new TreeField(new TreeCallback(), Manager.FOCUSABLE);
    tree.setDefaultExpanded(false);
    tree.setIndentWidth(10);
    Account[] accounts = accountManager.getAccounts(AccountManager.PARENT_ROOT_ID);
    if (accounts.length == 0) {
      FontFamily fontFamily[] = FontFamily.getFontFamilies();
      Font font = fontFamily[3].getFont(FontFamily.SCALABLE_FONT, 12);
      tree.setFont(font.derive(Font.PLAIN));
      tree.setEmptyString("Empty", DrawStyle.HCENTER);
    } else {
      if (accounts[0].getParentId() == AccountManager.PARENT_ROOT_ID) {
        TreeNode item = new TreeNode(accounts[0], accountManager);
        currentParentNode = tree.addChildNode(0, item);
        if (!item.isLocked()) {
          item.setExpanded(true);
          setNodes(accountManager.getAccounts(AccountManager.ROOT_ID));
        } else {
          EventInjector.invokeEvent(new EventInjector.TrackwheelEvent(EventInjector.TrackwheelEvent.THUMB_CLICK,
              1, KeyListener.STATUS_TRACKWHEEL));
        }
      }
    }
    vfm.add(tree);
    add(vfm);
  }
 
  public void setNodes(Account[] accounts) {
    //int count = getAccountsCount(accounts);
    //int size = accounts.length;
    //sort(accounts, 0, count);
    //sort(accounts, count, size);
    if (accounts.length > 0) {
      sort(accounts);
      int id = tree.addChildNode(currentParentNode, new TreeNode(accounts[0], accountManager));
      for (int i = 1; i < accounts.length; i++) {
        //tree.addChildNode(currentParentNode, new TreeNode(accounts[i], accountManager));
        id = tree.addSiblingNode(id, new TreeNode(accounts[i], accountManager));
      }
      if (currentParentNode != 0) { // in order not to expand the parent of the root (it doesn't exist)
        tree.setExpanded(currentParentNode, true);
        TreeNode node = (TreeNode) tree.getCookie(currentParentNode);
        node.setExpanded(true);
      } else {
        tree.setExpanded(currentNode, true);
        TreeNode node = (TreeNode) tree.getCookie(currentNode);
        node.setExpanded(true);
      }
    }
  }
   
  private void sort(Account[] accounts) {
    for (int i = 0; i < accounts.length - 1; i++) {
      for (int j = i + 1; j < accounts.length; j++) {
        if (accounts[i].isGroup()) {
          if (accounts[j].isGroup()) {
            if (accounts[i].getName().compareTo(accounts[j].getName()) < 0) {
              Account temp = accounts[i];
              accounts[i] = accounts[j];
              accounts[j] = temp;
            }
          }
        } else {
          if (accounts[j].isGroup()) {
            Account temp = accounts[i];
            accounts[i] = accounts[j];
            accounts[j] = temp;
          } else {
            if (accounts[i].getName().compareTo(accounts[j].getName()) > 0) {
              Account temp = accounts[i];
              accounts[i] = accounts[j];
              accounts[j] = temp;
            }
          }
        }
      }
    }
  }
 
  public void deleteNodes() {
    int n = tree.getFirstChild(currentParentNode);
    int k = n;
    while (n != -1) {
      k = tree.getNextSibling(n);
      tree.deleteSubtree(n);
      n = k;
    }
  }
 
  public Account getRootNode() {
    return ((TreeNode) tree.getCookie(tree.getFirstRoot())).getAccount();
  }
 
  public Account getAccount() {
    setCurrentNode();
    TreeNode node = (TreeNode) tree.getCookie(currentNode);
    currentParentNode = tree.getParent(currentNode);
    return node.getAccount();
  }
 
  public void setCurrentNode() {
    currentNode = tree.getCurrentNode();
  }
 
  public long getParentAccountId() {
    setCurrentNode();
    TreeNode item = (TreeNode) tree.getCookie(currentNode);
    if (item.isGroup()) {
      currentParentNode = currentNode;
    } else {
      currentParentNode = tree.getParent(currentNode);
      item = (TreeNode) tree.getCookie(currentParentNode);
    }
    return item.getAccountId();
  }
 
  public int getDepth() {
    //System.out.println("Get Depth 1: " + currentParentNode);
    if (currentParentNode == 0) {
      return 0;
    }
    //System.out.println("Get Depth 2");
    int depth = 0;
    int parentId = currentParentNode;
    //System.out.println("Get Depth 3");
    while (parentId > 0) {
      //System.out.println("Get Depth 4: " + parentId);
      depth++;
      parentId = tree.getParent(parentId);
      //System.out.println("Get Depth 5: " + depth);
    }
    //System.out.println("Get Depth 6: " + depth);
    return depth;
  }
 
  public int getCurrentParentNode() {
    return currentParentNode;
  }
 
  public Account deleteNode() {
    int curNode = tree.getCurrentNode();
    TreeNode item = (TreeNode) tree.getCookie(curNode);
    tree.deleteSubtree(curNode);
    return item.getAccount();
  }
 
  private int getCount(int node) {
    int count = 0;
    int n = tree.getFirstChild(node);
    while (n != -1) {
      count++;
      n = tree.getNextSibling(n);
    }
    return count;
  }
 
  public void lockGroup() {
    //System.out.println("Lock 3.1");
    //deleteNodes();
    //System.out.println("Lock 3.2");
    TreeNode item = (TreeNode) tree.getCookie(currentNode);
    //System.out.println("Lock 3.3");
    item.setLockedIcons();
    //System.out.println("Lock 3.4");
    tree.setExpanded(currentNode, false);
    //System.out.println("Lock 3.5");
    item.setExpanded(false);
    //System.out.println("Lock 3.6");
  }
 
  /**
  * @see net.rim.device.api.ui.container.HorizontalFieldManager#sublayout(int, int)
  *
  * @param width - int
  * @param height - int
  */
  public void sublayout(int width, int height) {
    super.sublayout(prefWidth, prefHeight);
    setExtent(prefWidth, prefHeight);
  }
 
  /**
  * @see net.rim.device.api.ui.container.HorizontalFieldManager#getPreferredWidth()
  *
  * @return int
  */
  public int getPreferredWidth() {
    return prefWidth;
  }
 
  /**
  * @see net.rim.device.api.ui.container.HorizontalFieldManager#getPreferredHeight()
  *
  * @return int
  */
  public int getPreferredHeight() {
    return prefHeight;
  }
 
  public boolean trackwheelClick() {
    int node = tree.getCurrentNode();
    TreeNode item = (TreeNode) tree.getCookie(node);
    AccountImpl account =(AccountImpl) item.getAccount();
    //System.out.println("Account ID: " + account.getId());
    if (account.isGroup()) {
      if(tree.getExpanded(node)) {
        item.setExpanded(false);
        tree.setExpanded(node, false);
      } else {
        //System.out.println("Putkooooooou maina");
        if (accountManager.isGroupLocked(account)) {
          EnterPassDialog enterPass = new EnterPassDialog();
          enterPass.open();
          if (!enterPass.isCancelPressed()) {
            if (!accountManager.unlockGroup(account, enterPass.getPass())) {
              Dialog.alert("Wrong password!");
              return true;
            }
            item.setUnlockedIcons();
          } else {//cancel button is pressed
            return true;
          }
        }
        //System.out.println("Kopeleeee 1");
        Account[] accounts = accountManager.getAccounts(account.getId());
        //System.out.println("Kopeleeee 2: " + currentParentNode);
        if (accounts.length != getCount(node)) {
          currentParentNode = node;
          //System.out.println("Kopeleeee 3: " + currentParentNode);
          setNodes(accounts);
        } else {
          tree.setExpanded(node, true);
        }
        item.setExpanded(true);
      }
    }
    return true;
  }
 
  /**
  * If a parent node is clicked - the node is getting expanded or not. If a
  * child node (check box field) is clicked - the node is getting checked
  * or not. The last case is when the "ok" button is clicked.
  *
  * @see net.rim.device.api.ui.Manager#trackwheelClick(int, int)
  *
  * @param status - int
  * @param time - int
  */
  protected boolean trackwheelClick(int status, int time) {
    return trackwheelClick();
  }
 
  /**
  * @see net.rim.device.api.ui.component.TreeFieldCallback
  */
  private class TreeCallback implements TreeFieldCallback {
   
    /**
    * @see net.rim.device.api.ui.component.TreeFieldCallback#drawTreeItem(net.rim.device.api.ui.component.TreeField, net.rim.device.api.ui.Graphics, int, int, int, int)
    *
    * @param treeField - TreeField
    * @param graphics - Graphics
    * @param node - int
    * @param y - int
    * @param width - int
    * @param indent - int
    */
    public void drawTreeItem(TreeField treeField, Graphics graphics, int node, int y, int width, int indent) {
      FontFamily fontFamily[] = FontFamily.getFontFamilies();
      Font font = fontFamily[3].getFont(FontFamily.SCALABLE_FONT, 12);
      graphics.setFont(font);
      TreeNode cookie = (TreeNode) treeField.getCookie(node);
      cookie.setY(y);
      cookie.setIndent(indent - 20);
      cookie.paint(graphics);
    }
   
  }
 
}

and the TreeNode class:
Code:

public class TreeNode extends Field {
  /** a title for the node */
  private String title;
  /** icons bitmap */
  private Bitmap iconOpened;
  private Bitmap iconClosed;
  private Account account = null;
 
  /** indicates if the node is clicked or not */
  private boolean nodeExpanded = false;
  /**  */
  private boolean isGroup = false;
  private boolean isLocked = false;
 
  /** the x coordinate for the node to be placed */
  private int indent;
  /** the y coordinate for the node to be placed */
  private int y;
  /** the length of the text area of the node */
  private int textLength;
 
  /**
  * Constructs a new node for a tree field with the argument title and icon bitmap.
  *
  * @param title - String
  * @param iconName - String
  */
  public TreeNode(Account account, AccountManager accountManager) {
    System.out.println("Kopeleeee 2.2.1");
    title = account.getName();
    System.out.println("Kopeleeee 2.2.2");
    String icon = account.getIcon();
    System.out.println("Kopeleeee 2.2.3");
    if (account.isGroup()) {
      isGroup = true;
      System.out.println("Kopeleeee 2.2.4");
      if (accountManager.isLocked(account.getId())) {
        System.out.println("Kopeleeee 2.2.5");
        isLocked = true;
        icon = "iconlocked.png";
      } else if (account.getEncrPassword() != null) {
        System.out.println("Kopeleeee 2.2.6");
        iconOpened = Bitmap.getBitmapResource("iconopenunlocked.png");
        icon = "iconunlocked.png";
      } else {
        iconOpened = Bitmap.getBitmapResource("iconopen.png");
        icon = "iconclosed.png";
      }
    }
    System.out.println("Kopeleeee 2.2.7");
    iconClosed = Bitmap.getBitmapResource(icon);
    this.account = account;
  }
 
  /**
  * @see net.rim.device.api.ui.Field#paint(net.rim.device.api.ui.Graphics)
  *
  * @param g - Graphics
  */
  public void paint(Graphics g) {
    //g.rop(Graphics.ROP_SRC_COPY, indent + 1, y + 2, 17, mask.getHeight(), mask, 0, 0);
    if (nodeExpanded) {
      g.drawBitmap(indent, y + 1, 17, iconOpened.getHeight(), iconOpened, 0, 0);
    } else {
      g.drawBitmap(indent, y + 1, 17, iconClosed.getHeight(), iconClosed, 0, 0);
    }
    g.drawText(title/* + ": " + account.getId() + ": " + account.getParentId()*/, indent + 18, y + 4, Graphics.ELLIPSIS, textLength);
  }
 
  /**
  * Sets the position of the node to the screen.
  *
  * @param x - int
  * @param y - int
  */
  public void setThePosition(int x, int y) {
    super.setPosition(x, y);
  }
 
  /**
  * Sets the width and height of the node i.e. the layout.
  *
  * @param width - int
  * @param height - int
  */
  public void setLayout(int width, int height) {
    layout(width, height);
  }
 
  /**
  * @see net.rim.device.api.ui.Field#layout(int, int)
  *
  * @param width - int
  * @param height - int
  */
  public void layout(int width, int height) {
    setExtent(width, height);
  }
 
  /**
  * Gets the title of the node
  *
  * @return String
  */
  public String getTitle() {
    return title;
  }
 
  /**
  * Returns if the node is expanded or not.
  *
  * @return boolean
  */
  public boolean getExpanded() {
    return nodeExpanded;
  }
 
  /**
  * Sets the node expanded state.
  *
  * @param nodeExpanded - boolean
  */
  public void setExpanded(boolean nodeExpanded) {
    this.nodeExpanded = nodeExpanded;
  }
 
  /**
  * Sets indent.
  *
  * @param indent - int
  */
  public void setIndent(int indent) {
    this.indent = indent;
    textLength = Display.getWidth() - indent - 22;
  }
 
  /**
  * Sets y coordinate.
  *
  * @param y - int
  */
  public void setY(int y) {
    this.y = y;
  }

  public boolean isGroup() {
    return isGroup;
  }

  public void setGroup(boolean isGroup) {
    this.isGroup = isGroup;
  }
 
  public long getAccountId() {
    return account.getId();
  }
 
  public Account getAccount() {
    return account;
  }

  public boolean isLocked() {
    return isLocked;
  }

  public void setLocked(boolean isLocked) {
    this.isLocked = isLocked;
  }
 
  public void setUnlockedIcons() {
    iconClosed = Bitmap.getBitmapResource("iconunlocked.bmp");
    iconOpened = Bitmap.getBitmapResource("iconopenunlocked.bmp");
  }
 
  public void setLockedIcons() {
    isLocked = true;
    iconClosed = Bitmap.getBitmapResource("iconlocked.bmp");
  }
 
}

.
I don't know if it will help you but thanks in advance if you are going to read it. There are a lot of lines commented, I am sorry about that. What is this "debugger's memory snapshot utility", in fact I cannot debug (I am using Eclipse, but the debugger doesn't work for me) I don't know why?

pa4o85 08-06-2008 10:27 AM

I remind something. I used the net.rim.device.api.system.RealtimeClockListener that has clockUpdated() method, and this method is reached everytime the clock changes i.e. every minute. I will test if the application will go faster is the listener is removed.


All times are GMT -5. The time now is 01:37 AM.

Powered by vBulletin® Version 3.6.12
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.