2006年02月22日

看到一篇较为古老的“文章”, 于是自己写代码实现了一下,发现果然有很大的差别。

我写了一个简单的测试程序,核心部分就是

            // Read One
            while ((isStream.read()) != -1) readLen++;
           
            // Read Buffer

            while ((readOnce = isStream.read(buffer, 0, buffer.length)) != -1)
            { readLen+=readOnce; }


思路是对一个大小为100,000字节的文件全部读取一遍,一种是采用ReadOne方式,另一种是采用ReadBuffer的方式,然后通过消耗的时间来比较哪种方法更高效。

在标准模拟器上的结果如下:

ReadOne:
ReadOne


ReadBuf:
Read Buffer

采用ReadOne方式消耗了2043毫秒,而采用ReadBuf方式消耗了<0毫秒。

另选用了两款手机进行三次测试,结果如下:

Nokia6260
    ReadOne: 125     94     188
    ReadBuf: 31     31     15

MotoE398
    ReadOne: 6102     6135     6192
    ReadBuf: 18     17     18

所以,采用ReadBuf的方式,还是对性能可能有显著的提高。

附上源码,如果你有手机,也可以测试一下。
/*
 * HelloMidlet.java
 *
 */

package hello;

import java.io.IOException;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.InputStream;

/**
 *
 * @author Vince
 */
public class HelloMidlet extends MIDlet implements javax.microedition.lcdui.CommandListener {
    String fileStringName="/test.bin";
    /** Creates a new instance of HelloMidlet */
    public HelloMidlet() {
    initialize();
    }
   
    private javax.microedition.lcdui.Form helloForm;                    
    private javax.microedition.lcdui.Command exitCommand;
    private javax.microedition.lcdui.Command readOneCommand;
    private javax.microedition.lcdui.Command readBufCommand;
    private javax.microedition.lcdui.StringItem stringItem1;
    private javax.microedition.lcdui.StringItem stringItem2;                  
   
    /** This method initializes UI of the application.                     
     */
    private void initialize() {
    getDisplay().setCurrent(get_helloForm());
    }                   
   
    /** Called by the system to indicate that a command has been invoked on a particular displayable.                     
     * @param command the Command that ws invoked
     * @param displayable the Displayable on which the command was invoked
     */
    public void commandAction(javax.microedition.lcdui.Command command, javax.microedition.lcdui.Displayable displayable) {                   
    // Insert global pre-action code here

    if (displayable == helloForm) {                    
        if (command == exitCommand) {                  
        // Insert pre-action code here
        exitMIDlet();                      
        // Insert post-action code here
        } else if (command == readOneCommand) {                    
        // Insert pre-action code here
        try {
            InputStream isStream = getClass().getResourceAsStream("/hello/test.bin");
            long preTime = System.currentTimeMillis();
            int readLen = 0;
            while ((isStream.read()) != -1) readLen++;
            long postTime = System.currentTimeMillis();
            isStream.close();
            isStream = null;
            get_stringItem2().setText("get"+readLen+"; elapse:" + (postTime – preTime));
        }
        catch (Exception e) {
            helloForm.append(new StringItem("Exception", e.getMessage()));
        }
        // Do nothing                      
        // Insert post-action code here
       
        } else if (command == readBufCommand) {                    
        // Insert pre-action code here
        byte[] buffer = new byte[4096];
        try {
            InputStream isStream = getClass().getResourceAsStream("/hello/test.bin");
            long preTime = System.currentTimeMillis();
            int readLen = 0;
            int readOnce = 0;
            while ((readOnce = isStream.read(buffer, 0, buffer.length)) != -1)
            readLen+=readOnce;
            long postTime = System.currentTimeMillis();
            isStream.close();
            isStream = null;
            get_stringItem2().setText("get"+readLen+"; elapse:" + (postTime – preTime));
        }
        catch (Exception e) {
            helloForm.append(new StringItem("Exception", e.getMessage()));
        }
        // Do nothing                       
       
        // Insert post-action code here
        buffer = null;
        }                      
    }                    
    // Insert global post-action code here
}                  
   
    /**
     * This method should return an instance of the display.
     */
    public javax.microedition.lcdui.Display getDisplay () {                        
    return javax.microedition.lcdui.Display.getDisplay(this);
    }                       
   
    /**
     * This method should exit the midlet.
     */
    public void exitMIDlet () {                        
    getDisplay().setCurrent(null);
    destroyApp(true);
    notifyDestroyed();
    }                       
   
    /** This method returns instance for helloForm component and should be called instead of accessing helloForm field directly.                       
     * @return Instance for helloForm component
     */
    public javax.microedition.lcdui.Form get_helloForm() {
    if (helloForm == null) {                     
        // Insert pre-init code here
        helloForm = new javax.microedition.lcdui.Form(null, new javax.microedition.lcdui.Item[] {                      
        get_stringItem1(),
        get_stringItem2()
        });
        helloForm.addCommand(get_exitCommand());
        helloForm.addCommand(get_readOneCommand());
        helloForm.addCommand(get_readBufCommand());
        helloForm.setCommandListener(this);                    
        // Insert post-init code here
    }                     
    return helloForm;
    }                   
   
   
    /** This method returns instance for exitCommand component and should be called instead of accessing exitCommand field directly.                       
     * @return Instance for exitCommand component
     */
    public javax.microedition.lcdui.Command get_exitCommand() {
    if (exitCommand == null) {                     
        // Insert pre-init code here
        exitCommand = new javax.microedition.lcdui.Command("Exit", javax.microedition.lcdui.Command.EXIT, 1);                     
        // Insert post-init code here
    }                     
    return exitCommand;
    }                   

    /** This method returns instance for readOneCommand component and should be called instead of accessing readOneCommand field directly.                       
     * @return Instance for readOneCommand component
     */
    public javax.microedition.lcdui.Command get_readOneCommand() {
    if (readOneCommand == null) {                     
        // Insert pre-init code here
        readOneCommand = new javax.microedition.lcdui.Command("ReadOne", javax.microedition.lcdui.Command.ITEM, 1);                     
        // Insert post-init code here
    }                     
    return readOneCommand;
    }                   
 
    /** This method returns instance for readBufCommand component and should be called instead of accessing readBufCommand field directly.                        
     * @return Instance for readBufCommand component
     */
    public javax.microedition.lcdui.Command get_readBufCommand() {
    if (readBufCommand == null) {                      
        // Insert pre-init code here
        readBufCommand = new javax.microedition.lcdui.Command("ReadBuf", javax.microedition.lcdui.Command.ITEM, 2);                      
        // Insert post-init code here
    }                      
    return readBufCommand;
    }                    

    /** This method returns instance for stringItem1 component and should be called instead of accessing stringItem1 field directly.                        
     * @return Instance for stringItem1 component
     */
    public javax.microedition.lcdui.StringItem get_stringItem1() {
    if (stringItem1 == null) {                      
        // Insert pre-init code here
        stringItem1 = new javax.microedition.lcdui.StringItem("Welcome", "Choose \"ReadOne\" menu item or \"ReadBuf\" menu item to see the time spending of reading stream(100,000 bytes)");                      
        // Insert post-init code here
    }                      
    return stringItem1;
    }                    

    /** This method returns instance for stringItem2 component and should be called instead of accessing stringItem2 field directly.                        
     * @return Instance for stringItem2 component
     */
    public javax.microedition.lcdui.StringItem get_stringItem2() {
    if (stringItem2 == null) {                      
        // Insert pre-init code here
        stringItem2 = new javax.microedition.lcdui.StringItem("Microsecond", "0");                      
        // Insert post-init code here
    }                      
    return stringItem2;
    }                    
   
    public void startApp() {
    }
   
    public void pauseApp() {
    }
   
    public void destroyApp(boolean unconditional) {
    }
   
}



2006年02月03日

首先,去除“自私”一词的贬义色彩,然后,人是自私的。何以见得?

家有一猫,不日,抱起,双手伸出阳台。视其鬼哭狼嚎状,遂抱回并以小鱼安慰之。

假设以我对猫的行为理解没有错误的话,它是在害怕,害怕什么呢?我家猫猫随我时日不短,假设耳濡目染掌握了一些基本的逻辑思维,并能够估计到这个高度已经超越了它能够挑战的极限的话,那么,它害怕的就是死亡。

任何的活物,具有自我了断能力的活物,都该怕死,如若不然,该物种就不会存活至今。出于对死亡的恐惧和对自我个体生命的维护,这种天生的能力便是自私的基本构成。

在每个人的心底,都有着要维护的东西。除去上述的生命,还有糖果,学校,英雄的形象,家族的荣誉,国家,后代的幸福,世界的和平等等等等。

画一个圈,把自己包括进去,圈内便是要维护的东西(不以多少来定圈的大小),属于自私的范畴,圈内与圈外的关系,是格格不入的关系。

很多时候,我们在苦苦思索解决圈内外的矛盾的时候,是否意识到,一个简单的方法就是把圈子画大一点,还有矛盾?再大一点。当圈子无限扩大,没有边界,就成了无私。

想一想自己的圈子画在什么地方,是否画的对,应该是一件很重要的事。