Raymond
          Java筆記

          2006年2月19日

          在Java高效編程里面看到變量一個ArrayList的時候,有兩種方式:
          假設(shè)a是個ArrayList

          1、 for (int i=0;i<a.size();i++) {
          2、 for (int i=0,n=a.size();i<n;i++) {

          帶著點懷疑我做了一下試驗,的確是方法2快一點的,估計是a.size()方法里面花費了一點多余的時間。后來我想到j(luò)dk 1.5開始還有一種遍歷的for/each方法,我做了一下比較,結(jié)果有點驚訝。

          源程序如下

           1import 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

          通過Profiling工具看結(jié)果:
          方法      運行時間
          testOne   0.055764
          testTwo  0.043821
          testThres 0.132451

          也就是說,jdk 1.5的for/each循環(huán)是最慢的。有點不相信。開頭覺得是因為賦值造成的,但后來在另兩個方法里面加上賦值語句,依然是for/each最慢。比較有趣的結(jié)果。

          從代碼清晰角度,用for/each消耗多一點點時間似乎也無所謂。但是,另兩種代碼也不見得“不清晰”,呵呵。看著辦了。

          posted @ 2006-03-03 12:00 Raymond的Java筆記 閱讀(501) | 評論 (0)編輯 收藏
           

          JMeter是apache的jakarta上面的項目,用于軟件的壓力測試(Load Test),不但可以對HTTP,也可以對數(shù)據(jù)庫(通過JDBC)、FTP、Web Service、Java 對象等等進行壓力測試。

          項目地址:http://jakarta.apache.org/jmeter

          使用: 運行bin目錄下的jmeterw.bat,運行jmeter.bat也可以,不過就會有一個命令窗口顯示。

          要提醒一下的是jmeter根據(jù)當前系統(tǒng)的locale顯示菜單的語言,為了方便想設(shè)置回英文的話,可以修改jmeter.properties文件,設(shè)置language=en  (我下載的2.1.1版本把“退出”誤譯為“推出”,怎么看都不順眼

          使用:

          JMeter的測試計劃(Test Plan)呈樹狀結(jié)構(gòu),樹里面有多種元素類型,樹狀結(jié)構(gòu)的元素之間有的是有繼承關(guān)系的(其原理有點類似log4j)。下面簡述一下元素類型:

          1、ThreadGroup
                顧名思義就是線程組,測試必須有一個ThreadGroup元素作為基礎(chǔ)(否則就沒有測試線程在跑了),這個元素可以配置跑多少個線程、每個線程循環(huán)多少次,所有線程數(shù)的總啟動時間(Ramp-up period)等等。

          2、Controller
               包括Logical Controller和Sampler,前者用來作一些邏輯上的控制,例如輪換、條件、循環(huán)等等。Sampler就是真正“干活”的“取樣器”,例如“HTTP Request”,就是拿來執(zhí)行一個HTTP請求的。

          3、Listener
              Listener對請求過程進行監(jiān)聽,可以簡單理解為獲取結(jié)果的東東。例如Simple Data Writer,可以把結(jié)果寫到一個文本文件里(其實所有Listener都可以寫數(shù)據(jù)到文件里),還有View Results in Table,就是把結(jié)果顯示在表格里。

          4、 Timer
              用來控制執(zhí)行流程中的時間延遲等功能。

          5、 Assertion
              斷言,加到Sampler里面可以對返回的結(jié)果進行判斷,例如判斷HTTP返回結(jié)果里面是否含有某個字符串。如果斷言為真,JMeter會標記請求為成功,否則標記為失敗。

          6、 Configuration Element
             
          配置用的元素,很有用。由于測試計劃是樹狀和有繼承關(guān)系的,可以在高層次指定一個Configuration Element,低層次的相關(guān)Sampler如果沒有顯式地指定配置,就繼承高層次的配置信息。(跟log4j很像吧?)

          7、 Pre-Processor/Post-Processor Elements
             用來在Sampler運行前和運行后作一些預處理和后處理工作的。例如動態(tài)修改請求的參數(shù)(預處理),從返回信息里面提取信息(后處理)等等。

          舉例:要做一個最簡單的HTTP壓力測試: 用10個線程訪問一個URL,每個線程訪問100次。
          做法:
          1、 在Test Plan下面加一個Thread Group,配置里面,線程數(shù)填10,循環(huán)次數(shù)填100
          2、 在Thread Group下面加一個HTTP Request,這是一個Sampler,在它的配置里面填寫主機信息,端口、協(xié)議、路徑、參數(shù)等信息
          3、 在HTTP Request下面加一個View Results in Table,如果你想把記錄記到文件,則填寫文件路徑。
          4、 保存一些這個Test Plan,就可以選擇Run菜單下面的Run來運行了。直到Run菜單項從灰色變回黑色,就表示運行完了。在View Results in Table下面,你可以看到運行結(jié)果。

          關(guān)于元素的詳細描述可以參考官方文檔

          JMeter功能很豐富的,還有很強的擴展能力,而且又是免費,值得研究使用。
          posted @ 2006-03-01 10:04 Raymond的Java筆記 閱讀(1581) | 評論 (0)編輯 收藏
           

          本文只作很簡要介紹,可視作備忘參考。

          TPTP是eclipse官方的profiling插件,初步使用下感覺功能強大。

          下載安裝: 在http://www.eclipse.org/tptp/下載,我選擇All-Runtime,然后像其它插件一樣解壓到eclipse的目錄,然后允許eclipse -clean來刷新一把。

          使用: 
             常用的profiling簡單來講就對程序運行進行記錄,然后從數(shù)據(jù)中分析哪些方法運行時間長,哪些對象吃內(nèi)存多,哪些類的實例多等等。一個比較好的使用入門sample在這里: http://www.eclipse.org/tptp/home/documents/tutorials/profilingtool/profilingexample_32.html 我就不羅嗦了。

          值得多講的是Remote Profiling,就是遠程剖析。實現(xiàn)的原理是在遠程機器上運行一個代理進程,要被遠程剖析的程序或者Application Server啟動的時候加一個JVM參數(shù)來識別這個代理進程,兩者相互作用,代理就可以把收集到的信息發(fā)給在遠程的一方(就是運行著eclipse的一方)。

          因此要實現(xiàn)Remote Profiling,還要在目標機器上裝一個agent。 -->

          下載安裝:http://www.eclipse.org/tptp/home/downloads/drops/TPTP-4.0.1.html 選擇對應操作系統(tǒng)的Agent Controller下載,選擇Runtime即可。

          下載后,閱讀依照getting_started.html的說明來安裝即可,這里簡述一下:
          1、 把它的bin目錄放到PATH里面
          2、 運行一下SetConfig來設(shè)置參數(shù),注意如果想讓除本地localhost意外所以機器都訪問的話,要注意設(shè)置Network Access Mode,默認是localhost的。
          3、 運行RAStart來啟動代理(Linux下)
          4、 服務器端程序(例如tomcat)啟動的JVM參數(shù)里面加入-XrunpiAgent:server=enabled即可(還有其它參數(shù)值參見文檔)
          5、 然后就可以在遠程用eclipse來啟動一個Profiling進程來attach到這個agent controller了。效果和在eclipse里面直接profile應用程序一樣。

          posted @ 2006-02-27 14:14 Raymond的Java筆記 閱讀(5643) | 評論 (2)編輯 收藏
           

          Volatile Fields

          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

          Brian Goetz coined the following "synchronization motto": "If you write a variable which may next be read by another thread, or you read a variable which may have last been written by another thread, you must use synchronization."


          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:

          1. 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.)

          2. 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.

          posted @ 2006-02-19 15:58 Raymond的Java筆記 閱讀(389) | 評論 (0)編輯 收藏
           
          主站蜘蛛池模板: 迁安市| 保康县| 沽源县| 离岛区| 佛山市| 渝中区| 昌乐县| 怀宁县| 柳林县| 宁陵县| 逊克县| 龙里县| 松原市| 黄平县| 宝坻区| 黔南| 鸡东县| 合水县| 汝阳县| 贵阳市| 连南| 公主岭市| 沂南县| 临朐县| 乌兰察布市| 昆山市| 沧源| 噶尔县| 名山县| 略阳县| 贺兰县| 黄陵县| 佛教| 梁河县| 名山县| 晋城| 台中市| 舞阳县| 兴安县| 泗洪县| 油尖旺区|