Java性能设计

很多程序员在一开始并不注重性能的设计,只有当系统交付运行时,才 发现问题并且开始解决这一问题,但往往这只能挽救一点点。性能的管理应该一开始 就被整合到设计和开发当中去。

最普遍的问题就是临时对象大量经常的创建,这为性能埋下隐患。

性能的问题来自很多原因,最容易解决的可能是:你选择了不好的算法来进行计算,如 用冒泡法来排序巨量数据,或者你每次使用数据时都要反复计算一次,这应该使用Cache。

你能很容易的使用工具(如Borland的Optimizeit)或压力测试发现这些问题, 一旦发现,就能够立即被纠正,但是很多Java的性能问题隐藏得更深,难于修改源码就能纠正, 如程序组件的接口设计。

现在我们倡导面向对象的组件可复用设计,无疑这样设计的优点是巨大的, 但是也要注意到对性能的影响。

一个java性能设计原则是,避免不必要的对象创建,对象的创建是非常耗时的, 所以你要避免不必要的临时或过多的对象创建,

String是程序中最主要创建的对象,因为String是不变的,如果String长度被修改 将导致String对象再次创建,所以对性能有所注意的一般人就是尽量回避使用String, 但是这几乎是不可能的。



接口参数设计

举例 MailBot:
MailBot邮件系统的有一个Header数据,它是character buffer,需要对这个character buffer 进行分析比较,那么你要做一个类Matcher,在这个类中你将Header数据读入然后配比, 一个不好的做法是:

public class BadRegExpMatcher {
  public BadRegExpMatcher(String regExp);

  /** Attempts to match the specified regular expression against the input     text, returning the matched text if possible or null if not
  */
  public String match(String inputText);

}

这个BadRegExpMatche要求入口参数是String ,那么如果MailBot要调用他,必须自己做一个 character buffer到String的转换:

BadRegExpMatcher dateMatcher = new BadRegExpMatcher(...);

while (...) { ...

//产生新的String
String headerLine = new String(myBuffer, thisHeaderStart, thisHeaderEnd-thisHeaderStart);

String result = dateMatcher.match(headerLine);

if (result == null) { ... }

}

很明显,这里这个由于接口不一致导致了多余的对象String headerline的创建,这是不能允许的, 应该将Matcher的接口设计成能够接纳character buffer,当然为通用性,也应该提供String的 接口参数:

class BetterRegExpMatcher {
  public BetterRegExpMatcher(...);

  /** 提供多个接口参数的match方法
  Provide matchers for multiple formats of input -- String,
  character array,   and subset of character array. Return
  -1 if no match was made; return offset of match start if
  a match was made. */
 
  public int match(String inputText);
  public int match(char[] inputText);
  public int match(char[] inputText, int offset, int length);

  /** Get the next match against the input text, if any */
  public int getNextMatch();

  public int getMatchLength();

  public String getMatchText();
}

很明显BetterRegExpMatcher的运行速度将比前面BadRegExpMatcher运行速度快。

因为在你已经写好代码的情况下,你比较难于更改一个类的接口参数,那就应该在写程序之前多 多考虑你这些接口参数的类型设定,最好有一个通盘的接口类型规定。



减少对象的创建

临时对象是那些有很短的生命周期,通常服务一些非十分有用的目标,程序员通常使用临时对象作为 数据混合包传送或者返回,为避免上述示例哪些转换接口对象的构造,你应该巧妙的避免创造这些临时 对象,以防止给你的程序留下性能的阴影。

上述示例说明性能问题在于String对象,但是String在对象创建中又是如此的普遍,String是不变的,一旦赋值,就不会变化,不少程序员 认为不变的东西总是会导致坏的性能,其实它并不是这么简单,实际上,性能好坏在于你如何使用这个东西。

对于经常需要变化的String,很明显使用Stringbuffer来代替。

举例:
看下面两种实现:

public class Component {
  ...
  protected Rectangle myBounds;
  public Rectangle getBounds() { return myBounds; }
}



public class Component {
  public Rectangle getBounds() {
    return new Rectangle(myBounds.x, myBounds.y, myBounds.height,    
                  myBounds.width);
  }
}

当使用Component分别对应有如下两种:

Rectangle r = component.getBounds();

...

r.height *= 2;


int x = component.getBounds().x;
int y = component.getBounds().y;
int h = component.getBounds().height;
int w = component.getBounds().width;

第一种使用方式缺点,r.height的使用已经脱离component,容易引起沟通上的误解,因为 Rectangle变化必须涉及component内容重新刷新,万一其它程序员不知道这个规则,修改 r.height(乘2),将不会去刷新component,

第二中方式是个提高,迫使componenet和其部件跟随在一起。但是带来问题是:创建了 四个临时对象。

改进办法是,在第一种的基础上,在Commponent中增加

public int getX() { return myBounds.x; }
public int getY() { return myBounds.y; }
public int getHeight() { return myBounds.height; }
public int getWidth() { return myBounds.width; }

这样调用变成:
int x = component.getX();
int y = component.getY();
int h = component.getHeight();
int w = component.getWidth();

两全其美了不是?

这就是减少创建对象技巧之一: 增加finer-grained辅助功能

第二种技巧是:Exploit mutability

上例还有一种实现方式:

public Rectangle getBounds(Rectangle returnVal) {
  returnVal.x = myBounds.x;
  returnVal.y = myBounds.y;
  returnVal.height = myBounds.height;
  returnVal.width = myBounds.width;
  return returnVal;

}

多巧妙,把Rectangle作为参数传进来修改一下再送出去。

技巧3是 融合变和不变于一身。

总结上面一些例子,发现一个规律:临时对象产生是在这种情况下产生的: 不变的要转换成可变的。那么针对这个根本原因我们设计出各取所需的方案。

以下例说明:

Point是不变的,我们继承它,定义一个可变的子类。

public class Point {
  protected int x, y;
  public Point(int x, int y) { this.x = x; this.y = y; }
  public final int getX() { return x; }
  public final int getY() { return y; }
}

public class MutablePoint extends Point {
  public final void setX(int x) { this.x = x; }
  public final void setY(int y) { this.y = y; }
}

这样,可变的需求和不可变的需求各自满足,分别调用。

public class Shape {
  private MutablePoint myLocation;

  //返回可变的
  public Shape(int x, int y) {
    myLocation = new MutablePoint(x, y);
  }

  //返回不变的
  public Point getLocation() { return (Point) myLocation; } }



远程接口

在分布式应用中,性能也是相当重要的,这里介绍如何通过检查class的接口 能简单预知分布式应用中的性能问题。

在分布式应用中,一个在这个系统中运行的对象能够调用另外一个系统的对象的方法,这是通过很多 内部机制来实现将远程对象貌似本地对象的,为了发现远程对象,你首先必须发现它,这是通过一种 名称目录服务机制,比如RMO的注册,JNDO和CORBA的名称服务。

当你通过目录服务得到一个远程的对象,你不是得到一个实际的指向,而是一个和远程行为一样的stub对象的 指向, 当你调用stub对象的一个方法时,这个得marshal这个方法参数:也就是转换成byte-stream,这类似 于序列化,这个stub对象通过网络将marshal后的参数发送给skeleton对象,后者负责unmarshal这些参数然后 调用真正实际的你要调用的远程方法,然后,这个方法返回一个值给skeleton,再逐个沿着刚才路线返回, 一个简单方法要做这么多工作啊。

很显然,远程方法调用要比本地方法调用来得耗时昂贵。

上面返回情况是是指返回原始型primitive,如果返回的是对象,怎么办?如果这个对象支持远程调用,它又会通过查询创造一个stub和skeleton对象,这又是耗时的;如果这个对象不支持远程调用,那么所有的对象的字段和任何涉及引用的对象都要被marshal,这也是 相当耗时的。

由此可见,一个不好的远程接口设计将完全扼杀程序的性能,为了避免网络开销,设计一次 远程调用返回多值总比多次调用,每次只返回一个值要好得多。

还有提防在不需要返回远程对象时,返回一个远程对象。不要传递很复杂不必要的对象给远程。

假设远程服务器有一个目录列表对象,每个目录项目中包含姓名 电话号码 和邮件地址等值, 下列程序:

public interface Directory extends Remote {
  DirectoryEntry[] getEntries();
  void addEntry(DirectoryEntry entry);
  void removeEntry(DirectoryEntry entry);

}

public interface DirectoryEntry extends Remote {
  String getName();
  String getPhoneNumber();
  String getEmailAddress();

}

这样设计导致结果是,当我需要一个姓名值时,首先要获得Directory 对象,再获得DirectoryEntry, 获得DirectoryEntry才能获得getName,这么来来回回,需要多少次网络开销啊。

public interface Directory extends Remote {
  String[] getNames();
  DirectoryEntry[] getEntries();

  //加入这个方法
  DirectoryEntry getEntryByName(String name);
  void addEntry(DirectoryEntry entry);
  void removeEntry(DirectoryEntry entry);

}

这样直接在Directory加上DirectoryEntry和getNames(),一次网络开销就全部解决。

当然这样的解决方案是完全建立在对分布式应用原理了解的基础上。



--------------转------------------

平均得分
(0 次评分)





文章来自: 本站原创
标签:
评论: 9 | 查看次数: 959
  • 共有 9 条评论
游客 [2008-11-19 14:03:50]
李小龙是Air Jordan shoes 一个天生的巨星,nike air jordan 一个天生的巨星cheap jordan shoes 三十二岁、五部电影,air jordan shoes 李小龙的女儿李香凝澄nike jordan shoes 清对李小龙的误读. wholesale jordan shoes李小龙多才多艺wholesale air jordans,亦文亦武。他每当练功wholesale air force one之余,埋头研究air force one wholesale武术理论与训练方法wholesale air force ones。他逝世前留下了七大本学武笔记和六本著作手稿air force ones wholesale
李小龙生于wholesale nike美国三藩市,他的童年和wholesale jordan shoes 少年是在香港度过的。jordan shoes wholesale 李小龙幼时身体非常瘦 wholesale air jordan 弱。他父亲为了儿子
air jordan wholesale 李小龙在wholesale gucci shoes西雅图的生活相当gucci shoes wholesale艰苦,进人大学wholesale air force one就读以后,他除air force one wholesale了学习外wholesale air force ones,把精力都放cheap jordan shoes在研习武术上。他在学校里组织了一支“中国功夫队”,经常在校园里air force ones wholesale进行训练和表演
父亲为了儿子wholesale jordan shoes1971年
游客 [2008-10-30 14:52:03]
buy wow gold Remember the WoW account hacking. buying gold world of warcraft If you're a WoW player. cheap wow gold you couldn't have missed . cheap wow gold any of the articles posting this issue. cheap wow gold Well, as it turns out, an article posted by . cheapest wow gold grimwell says that someone might have found the problem behind all the . eve isk account hacking, stealing and selling even 5 year's worth items. free online games A piece of the BBC news article says:"Analysis [. free online war games mp3 mp3 player ] showed that. mp3 players it lay dormant on a victims . mp4 machine until . online games they ran World of Warcraft (WoW) at which point it captured login data and sent it to. play war games the hacking group. sell wow gold The group's enthusiastic use of the cursor flaw suggests it is trying to . world of warcraft gold do the same again. wow The online fantasy game . wow gold now has more than eight million active players around the world. wow gold Research by security firm Symantec . wow gold suggests that the raw value of a WoW account is now higher. wow gold than a credit card and its associated verification data. wow gold "Normally, as a WoW player, you'd know about the risks involved when creating an online account, yet some were . wow gold lazy enough not to check on their accounts every once in a while, thus resulting in their items . wow gold kaufen and WoW currency being stolen. wow gold kaufen Everyone knows that . stuff like that happen, some. even managed to hack the Superbowl website and use it . to host code for spyware, so monitor the hell out of your computer!In an article I wrote yesterday. about hackers seeing console users as the new target, there is a comment coming from Stefana Muller.
游客 [2008-10-16 11:17:45]
游客 [2008-07-18 15:54:02]
Hey whats up guys New to the board.wow gold I'm in a bit of a dilema.wow gold welcome to my blog. mining and skinning as professions.world of warcraft gold I've made tons of with this guy.wow geld Enough money that I was able to buy.wow powerlevel my mount at level 40 with no problem at all.buy wow gold So now Im about to create an ALT toon and was wondering.wow which professions would compliment my.wow gold level 44 warrior and make me money at the same time.cheap wow gold One of my friends sayd I should go with disenchanting.serveur wow and blacksmithing but I don't know if there.wow europe is any money to be made in those.cheapest wow gold What do you guys think.wow power leveling Blacksmithing doesn't really pay off that well.wow powerleveling And I think that your warrior is geared quite well.gold wow so that the blacksmithing skill would have.mp3 players to be levelled quitea lot before you.mp3 player can make some nice and useful things.One crafting skill that compliments a warrior is alchemy.wow gold You can brew potions that he can consume.mp3 player and which are quite helpful in battle.zubehoer mp3 player There are potions to replenish lost health or rage.wow gold kaufen and there are battle and guardian elixirs to give you a boost.mp3 You could try enchanting to boost your warrior's gear.mp4 but then your other skill would have to be. mp4one where you can create green items (such as tailoring or leatherworking) to be disenchanted.
You can also send any useless greens you find with your warriorwow gold to your alt.but it's easier if you can also make your own.
游客 [2008-07-18 15:50:11]
Best place to start is in Bloodhoof Village in Mulgore.wow geld Go speak to Harn Longcast and buy Brilliant Smallfish him.mp3 players Now start fishing in Stonebull Lake.mp3 player Equip your rod and then apply the shiny bauble lure to it.wow level service as this will make catching fish easier.You'll want to catch about 60 Brilliant minutes.mp3 players You'll find that by the time you have Smallfish.mp3 player you'll also have about 30 Longjaw Mud Snappers.wow Once you have 60.mp3 players cook them.mp3 player You can own fire or jog back.wow gold to Harn Longcast and use the fire in front of him.wow schnell gold Cook the Brilliant Smallfish.gold für wow then at level 50 start cooking Longja.wow gold paypal Mud Snappers (after learning the recipe you bought earlier).You'll need to go and catch Longjaw.gold in wow Mud Snappers now and the place for these is.wow gold 1000 the pond in Orgrimmar by Lumark the Fishing trainer.wow power leveling (I know you've been catching quite a few where you are.wowgold but the "drop rate" is a lot better in Orgrimmar).Between levels 50 and 75 go and cooking.wowgold You'll now need to catch about 30 Longjaw 100.world of warcraft power leveling Now go to Mill in Hillsbrad and buy Bristle Whisker.wow golds Catfish recipe off of Derak Nightfall.cheapest wow gold Go to Mill and fish for Bristle Whisker Catfish.wow lvl Depending on your cooking level.world of warcraft power leveling Between levels 125 expert cooking from trainer.buy mp3 players You'll need and buy a book for your Fishing level.
Speak tobuy the book Expert Fishing: The Bass and You.Once your up to 175 cooking, go to Shadowprey Village in Desolace.
游客 [2008-07-18 15:44:26]
Hey whats up guys New to the board.wow gold I'm in a bit of a dilema.wow gold welcome to my blog. mining and skinning as professions.world of warcraft gold I've made tons of with this guy.wow geld Enough money that I was able to buy.wow powerlevel my mount at level 40 with no problem at all.buy wow gold So now Im about to create an ALT toon and was wondering.wow which professions would compliment my.wow gold level 44 warrior and make me money at the same time.cheap wow gold One of my friends sayd I should go with disenchanting.serveur wow and blacksmithing but I don't know if there.wow europe is any money to be made in those.cheapest wow gold What do you guys think.wow power leveling Blacksmithing doesn't really pay off that well.wow powerleveling And I think that your warrior is geared quite well.gold wow so that the blacksmithing skill would have.mp3 players to be levelled quitea lot before you.mp3 player can make some nice and useful things.One crafting skill that compliments a warrior is alchemy.wow gold You can brew potions that he can consume.mp3 player and which are quite helpful in battle.zubehoer mp3 player There are potions to replenish lost health or rage.wow gold kaufen and there are battle and guardian elixirs to give you a boost.mp3 You could try enchanting to boost your warrior's gear.mp4 but then your other skill would have to be. mp4one where you can create green items (such as tailoring or leatherworking) to be disenchanted.
You can also send any useless greens you find with your warriorwow gold to your alt.but it's easier if you can also make your own.
游客 [2008-07-18 15:42:34]
游客 [2008-05-27 11:34:10]
游客 [2008-05-19 14:56:32]
  • 共有 9 条评论
发表评论
昵 称:  登录
内 容:
选 项:
字数限制 1000 字 | UBB代码 开启 | [img]标签 开启