由HashMap的遍历看android的优化

no47wk 2012-07-14 11:54:47
  android的程序编写大部分时候都是用java,而android设备的性能多不是很高,所以对代码的优化是十分重要的,其中许多的优化技巧是可以从以往的PC平台JAVA优化技巧借鉴的。但是由于PC平台和嵌入式平台的硬件架构的巨大区别,导致盲目的采用以往的JAVA经验来优化android的代码可能会产生适得其反的后果。

  本文将就HashMap的遍历对这个问题进行一个初步的讨论。47K是新手程序猿,因此写的东西难免有所错漏,请您不吝赐教

  HashMap的遍历主要由两种方式:

  Solution I
Map map = new HashMap(); 
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}


  Solution II
Map map = new HashMap(); 
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}


在PC平台上,Solution I确实比II慢了不少

用时情况如下

KeySet 727
EntrySet 354

测试代码如下:
import java.io.ObjectInputStream.GetField;
import java.util.HashMap;
import java.util.Iterator;

/**
* @Title: test.java
* @Package
* @Description: TODO(用一句话描述该文件做什么)
* @author no47wk lotp,Come back
* @date 2012-7-14 上午11:02:23
* @version V1.0
*/

/**
* @ClassName: test
* @Description: TODO(这里用一句话描述这个类的作用)
* @author no47wk lotp,Come back
* @date 2012-7-14 上午11:02:23
*/
public class test {

public static void main(String[] args) {
test t=new test();
t.KeySet();
t.EntrySet();
}

private void KeySet() {
HashMap<String, String> map = getData();
Iterator<String> ite = map.keySet().iterator();
long start = System.currentTimeMillis();
while (ite.hasNext()) {
map.get(ite.next());
}
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("KeySet " + time + "");
}

private void EntrySet() {
HashMap<String, String> map = getData();
Iterator<java.util.Map.Entry<String, String>> ite = map.entrySet()
.iterator();
java.util.Map.Entry<String, String> entry;
long start = System.currentTimeMillis();
while (ite.hasNext()) {
entry = ite.next();
entry.getKey();
entry.getValue();
}
long end = System.currentTimeMillis();
long time = end - start;
System.out.println("EntrySet " + time + "");
}

private HashMap<String, String> getData() {
HashMap<String, String> ret = new HashMap<String, String>();
int i = 0;
while (i < 10000000) {
ret.put(String.valueOf(i), "a");
i++;
}
return ret;
}

}


但是在android平台上,两种方法的测试结果就非常接近了,甚至大部分情况下Solution I还比II更快一点,

用时情况如下

KeySet 5585
EntrySet 6515

测试代码如下
/**   
* @Title: Test.java
* @Package com.lotp.Test
* @Description: TODO(用一句话描述该文件做什么)
* @author no47wk lotp,Come back
* @date 2012-7-14 上午10:43:22
* @version V1.0
*/
package com.lotp.Test;

import java.util.HashMap;
import java.util.Iterator;

import android.app.Activity;
import android.os.Bundle;
import android.os.DropBoxManager.Entry;
import android.util.Log;

/**
* @ClassName: Test
* @Description: TODO(这里用一句话描述这个类的作用)
* @author no47wk lotp,Come back
* @date 2012-7-14 上午10:43:22
*/
public class Test extends Activity {

private HashMap<String, String> map;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
long start = System.currentTimeMillis();
map = getData();
KeySet();
EntrySet();
}
private void KeySet(){
Iterator<String> ite = map.keySet().iterator();
long start=System.currentTimeMillis();
while (ite.hasNext()) {
map.get(ite.next());
}
long end = System.currentTimeMillis();
Log.d("KeySet", end - start + " ");
}
private void EntrySet(){
Iterator<java.util.Map.Entry<String, String>> ite=map.entrySet().iterator();
java.util.Map.Entry<String, String> entry;
long start=System.currentTimeMillis();
while(ite.hasNext()){
entry=ite.next();
entry.getKey();
entry.getValue();
}
long end=System.currentTimeMillis();
Log.d("EntrySet", end-start+"");
}
private HashMap<String, String> getData() {
HashMap<String, String> ret = new HashMap<String, String>();
int i = 0;
while (i < 102400) {
ret.put(String.valueOf(i), "a");
i++;
}
return ret;
}
}


可见,对不同平台的代码的优化应该是因地制宜,强调针对性的,而不能笼统的采用同样的思路
...全文
670 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
no47wk 2012-07-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

这个和多线程有关

J2se部分的代码,只有一个主线程在跑

而在android模拟器里:
1.因为包含图形界面,模拟器本身就慢
2.模拟器需要加载整个android系统,需要模拟多进程,然后再你这个程序的进程里又是多线程

总的来说。执行速度肯定要慢下来不少。 如果你把 KeySet 和 EntrySet 各自再开线程去执行,花费的时间就更长了
[/Quote]
我觉得不是这个原因,我是跑在真机上的
RDroid 2012-07-14
  • 打赏
  • 举报
回复
这个和多线程有关

J2se部分的代码,只有一个主线程在跑

而在android模拟器里:
1.因为包含图形界面,模拟器本身就慢
2.模拟器需要加载整个android系统,需要模拟多进程,然后再你这个程序的进程里又是多线程

总的来说。执行速度肯定要慢下来不少。 如果你把 KeySet 和 EntrySet 各自再开线程去执行,花费的时间就更长了
no47wk 2012-07-14
  • 打赏
  • 举报
回复
囧,后边的代码里边可以看出区别,现在改不了了
一刀 2012-07-14
  • 打赏
  • 举报
回复
LZ,开头的Solution I和Solution II代码写重了

80,428

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧