草庐IT

dart - 如何处理在 Flutter 中搜索大型列表?

coder 2023-07-23 原文

我想问一下在Flutter中应该如何处理一个大列表。当我在我正在搜索的列表中非常深的数据项处时,我的应用程序变得非常慢。我的列表是一个大型数据结构的 70,000 多个对象。

以下是我“搜索”列表的方式。

Future<Iterable<SomeDataStruct>> _getAllData() async {
    return allData.where((a) => (a.dataTitle.toLowerCase().contains(querySearch.toLowerCase().trim())));
}

在 FutureBuilder 中使用 ListView.builder 构建列表。

当我搜索并填充来自列表深处的一个或多个结果时,应用程序非常慢,以至于我单击列表项并且需要几秒钟才能执行它的 onTap。如果我需要更改搜索查询,则在我单击 TextField 后软键盘需要一些时间才能恢复。

我在哪里犯了错误或处理错误,我应该怎么做才能让我的庞大列表可搜索而又不会让应用程序无法忍受。

编辑: 我如何让它在更改代码后不会减慢应用程序的速度。这是正确的吗?

String tempQuery;
List<SomeDataStruct> searchResults = [];
Future<List<SomeDataStruct>> _getAllData() async {
    if(querySearch!=tempQuery) {
      tempQuery = querySearch;
      searchResults = allData.where((a) => (a.dataTitle.toLowerCase().contains(querySearch.toLowerCase().trim()))).toList();
    }
    return searchResults;
  }

最佳答案

含贵

Contains-queries 是昂贵的,因为如果搜索词可以是找到了。

将搜索支持限制在字符串的开头会大大提高性能。此外,您可以创建辅助数据结构,其中整个值列表被分成开头具有相同字符的部分。如果 block 仍然太大,可以为第二个字符添加另一个级别。查找会很快,因为只有有限数量的字符。

使用数据库可能会减少一些编程工作(维护索引)。像 SQLite 这样的数据库可以与专门针对您的查询类型的索引一起使用。

拆分成更小的工作 block 以允许框架完成其工作

如果您不能限制为“字符串的开头”- 搜索,您仍然可以将数据结构拆分为更小的 block 并为每个 block 异步调用搜索。这样,在搜索下一个 block 之前,UI 会“呼吸一些空气”以重新呈现 UI。搜索结果将逐步更新。

将工作移出 UI 线程

另一种方法是启动另一个隔离区并在那里进行搜索。另一个 isolate 可以在另一个 CPU(核心)上运行,因此在搜索时不会阻塞 UI 线程。这样就没有必要分成 block 。尽管逐步更新 UI 而不是让用户等待整个搜索结果可用,但它可能仍然是有利的。

另见

缓存

将搜索结果保存在内存中也可能有助于提高性能。例如,如果用户输入 foo,然后按退格键,那么您可以重复使用您之前计算过的 fo 的搜索结果,但这仅在某些情况下有用。

测量

当然还有一个重点是做benchmarking。无论您尝试提高性能,创建基准以了解哪些措施有什么效果以及是否值得。您将学到很多关于场景、数据、Dart 等的知识,这将使您能够做出正确的决定。

关于dart - 如何处理在 Flutter 中搜索大型列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55043133/

有关dart - 如何处理在 Flutter 中搜索大型列表?的更多相关文章

  1. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  2. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  3. ruby-on-rails - 使用作为方法的值在 ruby​​ 中搜索哈希 - 2

    我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod

  4. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  5. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  6. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  7. ruby-on-rails - 如何在 Rails 4 中搜索关联 - 2

    我想获取主题名称与搜索关键字匹配的所有配置文件。现在我正在加载所有配置文件。我需要知道如何实现它。非常感谢任何帮助。配置文件.rbhas_many:categorizationshas_many:subjects,through::categorizations主题.rbhas_many:categorizationshas_many:profiles,through::categorizations分类.rbbelongs_to:profilebelongs_to:subjectviews/search/index.html.erb#searchform'get'do%>nil%>#

  8. Ruby:如何将数组拼接成 Lisp 风格的列表? - 2

    这是我发现自己偶尔想做的事情。假设我有一个参数列表。在Lisp中,我可以像这样`(imaginary-function,@args)为了调用将数组从一个元素转换为正确数量的参数的函数。Ruby中是否有类似的功能?或者我只是在这里使用了一个完全错误的成语? 最佳答案 是的!它被称为splat运算符。a=[1,44]p(*a) 关于Ruby:如何将数组拼接成Lisp风格的列表?,我们在StackOverflow上找到一个类似的问题: https://stackov

  9. ruby-on-rails - Ruby on Rails 将列表拆分或切片为列 - 2

    @locations=Location.all#currentlistingall@locations=Location.slice(5)orLocation.split(5)使用Ruby,我试图将我的列表分成4列,每列限制为5个;然而,切片或拆分似乎都不起作用。知道我可能做错了什么吗?任何帮助是极大的赞赏。 最佳答案 您可能想使用in_groups_of:http://railscasts.com/episodes/28-in-groups-of这是RyanBates在railscast中的示例用法:

  10. ruby - 在 Ruby 中搜索大文件的更简单方法? - 2

    我正在编写一个简单的日志嗅探器,它将在日志中搜索表明我支持的软件存在问题的特定错误。它允许用户指定日志路径并指定他们想要搜索多少天前。如果用户关闭日志滚动,日志文件有时会变得非常大。目前我正在做以下事情(虽然还没有完成):File.open(@log_file,"r")do|file_handle|file_handle.eachdo|line|ifline.match(/\d+++-\d+-\d+/)etc...line.match显然会查找我们在日志中使用的日期格式,其余逻辑将在下面。但是,有没有更好的方法来搜索没有.each_line的文件?如果没有,我完全同意。我只是想确保我使

随机推荐