查看: 2690|回复: 51

IStorageFolder.GetFilesAsync 之后读取多个 IStorageFile 的性能问题

[复制链接]

签到天数: 731 天

连续签到: 1 天

[LV.9]以坛为家II

55

主题

3262

积分

164

支持

发表于 2017-8-26 14:45:55 来自手机 | 显示全部楼层 |阅读模式

马上注册,享受积分奖励和更多功能,让您轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 tmp00000 于 2017-8-26 18:56 编辑

我在机械硬盘上创建了 1664 个 png 格式的图片,每一个图片 21.9 KB (22,496 字节)。
使用 UWP 的 FolderPicker 打开了那个存放了图片的文件夹, 使用 IStorageFolder.GetFilesAsync 打开每一个 png 文件, 读取全部内容到一个 Byte 数组,然后关掉它们。
筛选拓展名 png 分别用了 Linq 和 FileQuery 两种方式。这两种方式都需要 接近 6 秒来完成整个过程。
这个速度非常慢。
用 System.IO 的 API 实现等效的过程只需要不到 300 毫秒。
用 C++ 的 FindNextFile 与 用 System.IO 的性能非常接近。但是它在 UWP 上和 System.IO 一样只能对应用沙盒内的文件访问。
有什么好点子在 UWP 下优化效率?


来自:B150M-D3H WIN10 PC版客户端

签到天数: 299 天

连续签到: 138 天

[LV.8]以坛为家I

16

主题

2197

积分

0

支持

发表于 2017-8-26 15:09:22 来自手机 | 显示全部楼层
底层都不一样,很难比较的。知道它为什么慢才谈得上如何改,需要做专门测试才行。

来自:Lumia 830 -智机社区客户端
[你知道吗]:

签到天数: 11 天

连续签到: 1 天

[LV.3]偶尔看看II

2

主题

101

积分

22

支持

发表于 2017-8-26 15:15:40 来自手机 | 显示全部楼层
本帖最后由 MouriNaruto 于 2017-8-26 15:29 编辑

如果能提供测试用的图片包,我想试试看

PS:如果为了效率的话,建议学习微软使用C++开发UWP
[你知道吗]:

签到天数: 276 天

连续签到: 1 天

[LV.8]以坛为家I

46

主题

2083

积分

372

支持

开发者认证

Rank: 6Rank: 6

积分
2083
QQ

发表于 2017-8-26 16:00:07 | 显示全部楼层
MouriNaruto 发表于 2017-8-26 15:15
如果能提供测试用的图片包,我想试试看

PS:如果为了效率的话,建议学习微软使用C++开发UWP ...

跟C++没有关系,是微软的api的问题。
无吖

签到天数: 731 天

连续签到: 1 天

[LV.9]以坛为家II

55

主题

3262

积分

164

支持

 楼主| 发表于 2017-8-26 16:29:10 来自手机 | 显示全部楼层
MouriNaruto 发表于 2017-8-26 15:15
如果能提供测试用的图片包,我想试试看

PS:如果为了效率的话,建议学习微软使用C++开发UWP ...

C++ 也是用那一套 API。问题是那些 API 速度非常慢。
来自:B150M-D3H WIN10 PC版客户端
[你知道吗]:

签到天数: 731 天

连续签到: 1 天

[LV.9]以坛为家II

55

主题

3262

积分

164

支持

 楼主| 发表于 2017-8-26 16:30:12 来自手机 | 显示全部楼层
TonyDeng 发表于 2017-8-26 15:09
底层都不一样,很难比较的。知道它为什么慢才谈得上如何改,需要做专门测试才行。 ...

Windows Runtime 不是开源的。我不知道他们为什么把枚举文件和打开文件搞得那么慢。
来自:B150M-D3H WIN10 PC版客户端

签到天数: 11 天

连续签到: 1 天

[LV.3]偶尔看看II

2

主题

101

积分

22

支持

发表于 2017-8-26 16:33:59 | 显示全部楼层
wcavell 发表于 2017-8-26 16:00
跟C++没有关系,是微软的api的问题。

关于互操作优化(从Managed层转Native是有开销的,尽可能让转换次数越少越好或者干脆写成Native的)
https://docs.microsoft.com/zh-cn/windows/uwp/debug-test-perf/windows-runtime-components-and-optimizing-interop

关于文件访问的优化(我建议楼主看“C# 和 Visual Basic 中的数据流性能”这一段)
https://docs.microsoft.com/zh-cn/windows/uwp/debug-test-perf/optimize-file-access

[你知道吗]:

签到天数: 11 天

连续签到: 1 天

[LV.3]偶尔看看II

2

主题

101

积分

22

支持

发表于 2017-8-26 16:36:34 | 显示全部楼层
本帖最后由 MouriNaruto 于 2017-8-26 16:42 编辑
tmp00000 发表于 2017-8-26 16:30
Windows Runtime 不是开源的。我不知道他们为什么把枚举文件和打开文件搞得那么慢。 ...


因为StorageFile和StorageFolder需要通过RPC进程间通信让RuntimeBroker帮你打开文件(访问沙盒外的东西需要进程间通信)

而且WinRT提供的不少简单的读取接口都会给你进行多次不必要的拷贝

我建议直接从IInputStream拿raw buffer;不要用FileReader
在C#下把IInputStream转C#数组,我记得有很方便的成员函数

签到天数: 299 天

连续签到: 138 天

[LV.8]以坛为家I

16

主题

2197

积分

0

支持

发表于 2017-8-26 16:49:01 来自手机 | 显示全部楼层
tmp00000 发表于 2017-8-26 16:30
Windows Runtime 不是开源的。我不知道他们为什么把枚举文件和打开文件搞得那么慢。 ...

没开源所以说只能做测试了。根据你的描述,总数据量只有36M不到40M,但效率低,最大的可能是文件打开次数太多,估计与网络连接反复通断效率低的原因类似。要验证这个猜测,可以单独读一个40M的文件试试。在传统的C低级I/O读取操作上,block读和逐个byte读,差异很显著,即使是前者,调整块尺寸也有效果,甚至这与系统的缓存策略有关。这些因素都是猜测,到底真正的原因是什么,要测试验证。

来自:Lumia 830 -智机社区客户端
[你知道吗]:

签到天数: 731 天

连续签到: 1 天

[LV.9]以坛为家II

55

主题

3262

积分

164

支持

 楼主| 发表于 2017-8-26 16:50:55 来自手机 | 显示全部楼层
MouriNaruto 发表于 2017-8-26 16:36
因为StorageFile和StorageFolder需要通过RPC进程间通信让RuntimeBroker帮你打开文件(访问沙盒外的东西需 ...

那篇文章只是告诉我怎样用索引优化。只遍历文件名不打开文件在 1 楼 的测试中都需要 1200 毫秒。
来自:B150M-D3H WIN10 PC版客户端
您需要登录后才可以回帖 登录 | 注册

本版积分规则

         

网站地图| 小黑屋|京ICP证150706号|京B2-20160045| 京公网安备11010802018258号

Powered by Discuz! X3.2 / Copyright 2010-2017 © 智机网 WFUN.COM Inc. All rights reserved.

快速回复 返回顶部 返回列表