??xml version="1.0" encoding="utf-8" standalone="yes"?> 通过Profiling工具看结果:
1?for (int i=0;i<a.size();i++) {
2?for (int i=0,n=a.size();i<n;i++) {
带着Ҏ疑我做了一下试验,的确是方?快一点的Q估计是a.size()Ҏ里面p了一点多余的旉。后来我惛_jdk 1.5开始还有一U遍历的for/eachҎQ我做了一下比较,l果有点惊讶?BR>
源程序如?BR>
import java.util.ArrayList;
2
3public class ProfileArrayList
{
4
5 public static void main(String[] args)
{
6 ArrayList<String> s=new ArrayList<String>();
7 for (int i=0;i<15000;i++)
{
8 s.add(""+System.currentTimeMillis());
9 }
10 System.out.println("Start ");
11 testOne(s);
12 testTwo(s);
13 testThree(s);
14 System.out.println("End ");
15 }
16
17 private static void testOne(ArrayList<String> a)
{
18 int j=0;String s=null;
19 for (int i=0;i<a.size();i++)
{
20 s=a.get(i);
21 j++;
22 }
23 }
24
25private static void testTwo(ArrayList<String> a)
{
26 int j=0;
27 String s=null;
28 for (int i=0,n=a.size();i<n;i++)
{
29 s=a.get(i);
30 j++;
31 }
32 }
33
34private static void testThree(ArrayList<String> a)
{
35 int j=0;
36 for (String s : a)
{
37 j++;
38 }
39}
40
41}
42
Ҏ q行旉
testOne 0.055764
testTwo 0.043821
testThres 0.132451
也就是说Qjdk 1.5的for/each循环是最慢的。有点不怿。开头觉得是因ؓ赋值造成的,但后来在另两个方法里面加上赋D句,依然是for/each最慢。比较有的l果?BR>
从代码清晰角度,用for/each消耗多一点点旉g也无所谓。但是,另两U代码也不见得“不清晰”,呵呵。看着办了?/P>
目地址Qhttp://jakarta.apache.org/jmeter
使用Q?q行bin目录下的jmeterw.batQ运行jmeter.bat也可以,不过׃有一个命令窗口显C?BR>
要提醒一下的是jmeterҎ当前pȝ的locale昄菜单的语aQؓ了方便想讄回英文的话,可以修改jmeter.properties文gQ设|language=en Q我下蝲?.1.1版本把“退出”误译ؓ“推出”,怎么看都不顺?Q?BR>
使用Q?BR>
JMeter的测试计划(Test PlanQ呈树状l构Q树里面有多U元素类型,树状l构的元素之间有的是有承关pȝQ其原理有点cMlog4jQ。下面简qC下元素类型:
1?STRONG>ThreadGroup
思义是U程l,试必须有一个ThreadGroup元素作ؓ基础Q否则就没有试U程在跑了)Q这个元素可以配|跑多少个线E、每个线E@环多次Q所有线E数的d动时_Ramp-up periodQ等{?BR>
2?STRONG>Controller
包括Logical Controller和SamplerQ前者用来作一些逻辑上的控制Q例如轮换、条件、@环等{。Sampler是真正“干zZ的“取样器”,例如“HTTP Request”,是拿来执行一个HTTPh的?BR>
3?STRONG>Listener
Listener对请求过E进行监听,可以单理解ؓ获取l果的东东。例如Simple Data WriterQ可以把l果写到一个文本文仉Q其实所有Listener都可以写数据到文仉Q,q有View Results in TableQ就是把l果昄在表格里?BR>
4?Timer
用来控制执行程中的旉延迟{功能?BR>
5?Assertion
断言Q加到Sampler里面可以对返回的l果q行判断Q例如判断HTTPq回l果里面是否含有某个字符丌Ӏ如果断a为真QJMeter会标记请求ؓ成功Q否则标Cؓp|?BR>
6?Configuration Element
配置用的元素Q很有用。由于测试计划是树状和有l承关系的,可以在高层次指定一个Configuration ElementQ低层次的相关Sampler如果没有昑ּ地指定配|,q扉K层次的配|信息。(跟log4j很像吧?Q?BR>
7?Pre-Processor/Post-Processor Elements
用来在Samplerq行前和q行后作一些预处理和后处理工作的。例如动态修改请求的参数Q预处理Q,从返回信息里面提取信息(后处理){等?BR>
举例Q要做一个最单的HTTP压力试Q??0个线E访问一个URLQ每个线E访?00ơ?BR>做法Q?BR>1?在Test Plan下面加一个Thread GroupQ配|里面,U程数填10Q@环次数填100
2?在Thread Group下面加一个HTTP RequestQ这是一个SamplerQ在它的配置里面填写L信息Q端口、协议、\径、参数等信息
3?在HTTP Request下面加一个View Results in TableQ如果你x记录记到文gQ则填写文g路径?BR>4?保存一些这个Test PlanQ就可以选择Run菜单下面的Run来运行了。直到Run菜单从灰色变回黑色Q就表示q行完了。在View Results in Table下面Q你可以看到q行l果?BR>
关于元素的详l描q可以参?A >官方文档?BR>
JMeter功能很丰富的Q还有很强的扩展能力Q而且又是免费Q值得研究使用?/FONT>
TPTP是eclipse官方的profiling插gQ初步用下感觉功能强大?BR>
下蝲安装Q??A >http://www.eclipse.org/tptp/下蝲Q我选择AllQRuntimeQ然后像其它插g一栯压到eclipse的目录,然后允许eclipse -clean来刷C把?BR>
使用Q?nbsp;
常用的profiling单来讲就对程序运行进行记录,然后从数据中分析哪些Ҏq行旉长,哪些对象吃内存多Q哪些类的实例多{等。一个比较好的用入门sample在这里: http://www.eclipse.org/tptp/home/documents/tutorials/profilingtool/profilingexample_32.html 我就不罗嗦了?BR>
值得多讲的是Remote ProfilingQ就是远E剖析。实现的原理是在q程机器上运行一个代理进E,要被q程剖析的程序或者Application Server启动的时候加一个JVM参数来识别这个代理进E,两者相互作用,代理可以把攉到的信息发给在远E的一方(是q行着eclipse的一方)?BR>
因此要实现Remote ProfilingQ还要在目标机器上装一个agent?-->
下蝲安装Q?A >http://www.eclipse.org/tptp/home/downloads/drops/TPTP-4.0.1.html 选择对应操作pȝ?FONT color=#000000>Agent Controller下蝲Q选择Runtime卛_?BR>
下蝲后,阅读依照getting_started.html的说明来安装卛_Q这里简qC下:
1?把它的bin目录攑ֈPATH里面
2?q行一下SetConfig来设|参敎ͼ注意如果惌除本地localhost意外所以机器都讉K的话Q要注意讄Network Access ModeQ默认是localhost的?BR>3?q行RAStart来启动代理(Linux下)
4?服务器端E序Q例如tomcatQ启动的JVM参数里面加入-XrunpiAgent:server=enabled卛_Q还有其它参数值参见文档)
5?然后可以在q程用eclipse来启动一个Profilingq程来attach到这个agent controller了。效果和在eclipse里面直接profile应用E序一栗?BR>
Sometimes, it seems excessive to pay the cost of synchronization just to read or write an instance field or two. After all, what can go wrong? Unfortunately, with modern processors and compilers, there is plenty of room for error:
Computers with multiple processors can temporarily hold memory values in registers or local memory caches. As a consequence, threads running in different processors may see different values for the same memory location!
Compilers can reorder instructions for maximum throughput. Compilers won't choose an ordering that changes the meaning of the code, but they make the assumption that memory values are only changed when there are explicit instructions in the code. However, a memory value can be changed by another thread!
If you use locks to protect code that can be accessed by multiple threads, then you won't have these problems. Compilers are required to respect locks by flushing local caches as necessary and not inappropriately reordering instructions. The details are explained in the Java Memory Model and Thread Specification developed by JSR 133 (see http://www.jcp.org/en/jsr/detail?id=133). Much of the specification is highly complex and technical, but the document also contains a number of clearly explained examples. A more accessible overview article by Brian Goetz is available at http://www-106.ibm.com/developerworks/java/library/j-jtp02244.html.
NOTE
The volatile keyword offers a lock-free mechanism for synchronizing access to an instance field. If you declare a field as volatile, then the compiler and the virtual machine take into account that the field may be concurrently updated by another thread.
For example, suppose an object has a boolean flag done that is set by one thread and queried by another thread. You have two choices:
Use a lock, for example:
public synchronized boolean isDone() { return done; }
private boolean done;
(This approach has a potential drawback: the isDone method can block if another thread has locked the object.)
Declare the field as volatile:
public boolean isDone() { return done; }
private volatile boolean done;
Of course, accessing a volatile variable will be slower than accessing a regular variablethat is the price to pay for thread safety.
NOTE
![]() |
Prior to JDK 5.0, the semantics of volatile were rather permissive. The language designers attempted to give implementors leeway in optimizing the performance of code that uses volatile fields. However, the old specification was so complex that implementors didn't always follow it, and it allowed confusing and undesirable behavior, such as immutable objects that weren't truly immutable. |
In summary, concurrent access to a field is safe in these three conditions:
The field is volatile.
The field is final, and it is accessed after the constructor has completed.
The field access is protected by a lock.