【问题标题】:Using a HashMap to store large amounts of data is slowing down my Android app, are there other options?使用 HashMap 存储大量数据会降低我的 Android 应用程序的速度,还有其他选择吗?
【发布时间】:2014-01-11 21:18:01
【问题描述】:

我为我的学校编写了一个 Android 应用程序,它生成一个 HashMap,它将课程名称映射到该课程可用部分的 ArrayList(字符串)。使用JSoup生成地图,连接学校网站,获取当前所有课程信息,解析格式化,创建HashMap>()。

它有效。但是,在 Android 设备上生成 HashMap 实际上需要大约 5 分钟。我是编程方面的新手,我想知道是否还有其他更有效的方法来存储和处理如此大量的数据(HashMap 映射到大约 800 个 ArrayList,每个 ArrayList 又包含几个字符串)。理想情况下,每次应用程序运行时数据都会更新,所以我不确定写入内部存储是否有效。

有什么建议吗?

谢谢

编辑:这是创建 HashMap 的方法。这有点令人费解,但我从中提取数据的网站并不容易使用。

public HashMap<String, ArrayList<String>> generateCourseSectionMap()
        {
            ArrayList<String> store = new ArrayList<String>();
            CourseLinks courses = new CourseLinks();
            HashMap<String, String> courseLinks = courses.getCourseMap();
            StringUtils util = new StringUtils();

            HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();

            String sectionFormat = "((\\d){5};(\\d)+;(.*?) \\((.*?)\\);(.*?);(\\d)+ \\/ (\\d)+;(.*?);(TBA|Mo|Tu|We|Th|Fr|Sa|Su)+( (\\d){1,2}:(\\d){2}(AM|PM) - (\\d){1,2}:(\\d){2}(AM|PM))*?;(.*?));";

            Document doc;

            try
                {
                    for (Map.Entry<String, String> entry : courseLinks.entrySet())
                        {
                            doc = Jsoup.connect(entry.getValue()).get();

                            Elements links = doc.select("*+tr>*:not(tr[class~=SectionTopic.*]>*):not(tr[class~=SectionTitle.*]>*)");

                            if (!links.isEmpty())
                                links.remove(0);

                            String build = "";

                            for (Element e : links)
                                {
                                    String s = util.trim(e.text());
                                    if (!s.isEmpty())
                                        build = build + s + ";";
                                }

                            String rebuilt = rebuild(build);
                            store = util.toArrayList(rebuilt.split("BREAK"));

                            for (String d : store)
                                {
                                    Pattern p = Pattern.compile(sectionFormat, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
                                    Matcher m = p.matcher(d);

                                    String[] array = d.split(";");

                                    String firstKey = d.substring(0, d.indexOf(";"));

                                    ArrayList<String> sectionList = new ArrayList<String>();

                                    while (m.find())
                                        sectionList.add(array[0] + ";" + array[1] + ";" + m.group());

                                    map.put(firstKey, sectionList);
                                }
                        }
                }
            catch (IOException e)
                {
                    e.printStackTrace();
                }
            return map;
        }

【问题讨论】:

  • 确实有很多时间。您能否提供有关如何生成地图的更多详细信息?来源、基本算法、数组列表中的字符串长度...
  • 我猜大部分时间都花在了数据传输和解析上。 HashMap 中的 800 个条目应该很快。
  • 我用我正在使用的方法更新了问题。
  • 地图中的 800 个条目并不是“大量数据”。这没什么。它实际上应该是瞬时的。你找错地方了。
  • doc = Jsoup.connect(entry.getValue()).get();这会建立新的连接吗?

标签: java android performance jsoup


【解决方案1】:

首先,这个:

Pattern p = Pattern.compile(sectionFormat, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

for 循环中为每次迭代编译一个模式不是最理想的。
一开始编译一次,后面使用编译后的模式。

还有,这个:

build = build + s + ";";

由于build 是一个字符串,重复连接它将在每次迭代时在内存中创建新的字符串。
考虑改用StringBuilderappend 方法。

话虽如此,这些问题并不足以严重拖慢您的流程。

目前没有足够的信息让我快速注意到更多明显的问题,但似乎取决于找到的链接数量以及下载的页面数量,大部分时间可能都花在阅读上从网络和解析 HTML 页面。

您可能想要使用诸如http://developer.android.com/tools/debugging/debugging-tracing.html 之类的工具来查看发生了什么。

【讨论】:

  • 我认为您对连接页面所花费的时间是正确的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多