V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lithium148
V2EX  ›  编程

数组里有百万个值,如何加快速度?

  •  
  •   lithium148 · 32 天前 · 3072 次点击
    这是一个创建于 32 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Android 中,我有一个 int[] a,里面大约有两百万个 int

    每一个 a[i],经过一些简单的加减后,得到新的值

    实测这样的操作将会花费惊人的数分钟时间,

    请问如何加快这个速度?

    目前想到的是每几个 a[i]开一个新的线程,改用 synchronizedList,

    因为我看到耗时很长但是 CPU 占用率很低。

    还有别的方法吗?

    谢谢各位大佬不吝赐教,在下不尽感激

    35 条回复    2021-04-13 03:41:12 +08:00
    aheadlead
        1
    aheadlead   32 天前
    ……最好的办法就是少存点

    不过楼主可以详细描述下,或者直接贴代码
    des
        2
    des   32 天前 via iPhone
    每次更新两百万个数据,想快也快不起来吧?
    建议先想想,为啥每次需要更新这么多数据
    lithium148
        3
    lithium148   32 天前 via Android
    @des 具体的场景是,有一个 bitmap (图片),读取每一个像素点的 rgb 值,修改后回去。这里的应用是修改图片亮度。
    xupefei
        4
    xupefei   32 天前 via iPhone
    不要每几个值就开线程,把整个数组等分为 cpu 核数会更快。
    kera0a
        5
    kera0a   32 天前 via iPhone   ❤️ 1
    安卓能调 gpu 算吗?
    lithium148
        6
    lithium148   32 天前 via Android
    我看到其他人的代码,这一块是用 Ndk ( c++)实现的,但我不会 c++……
    lithium148
        7
    lithium148   32 天前 via Android
    @xupefei 最后又要从 n 个合成 1 个数组,多了复制的开销吧
    aheadlead
        8
    aheadlead   32 天前
    @lithium148 #3 这应该算是典型的用 native 的场景吧。。

    (不过我不是 app developer…
    akira
        9
    akira   32 天前   ❤️ 1
    提交给服务器端,处理完成后返回给客户端 @@
    aheadlead
        10
    aheadlead   32 天前
    没有封装好的库可以用吗?
    lithium148
        11
    lithium148   32 天前 via Android
    @aheadlead native 是指 ndk 吗,方便展开说说不
    Muniesa
        12
    Muniesa   32 天前   ❤️ 1
    用 opencv 不好吗,直接算矩阵不比你循环算数组快……
    xmumiffy
        13
    xmumiffy   32 天前 via Android   ❤️ 2
    建议用 colorMatrix
    des
        14
    des   32 天前 via iPhone
    首先图像计算建议用图像库
    要自己搞的话,你这明显有可以优化的地方
    一是颜色一般只需要存 255,你这浪费了好多
    然后黑白图又可以省好多
    还有是可以用 gpu 加速
    aheadlead
        15
    aheadlead   32 天前
    @lithium148 #11 我以前是做手机的 framework native 和 kernel 的… app 的 NDK 不算太熟

    不过我觉得你这个场景 100%有成熟的 library 可以用
    areless
        16
    areless   32 天前
    gpu.js 或者 webgl2 走 GPU 加速的。你只需要一个 headless 浏览器
    Mithril
        17
    Mithril   32 天前 via iPhone   ❤️ 1
    图像处理不是这么搞的。。。
    用 C++主要是因为可以用 SIMD 指令,但是一般来说如果只是做你说的亮度处理,不应该在图像本身上面搞。
    通常会做一个类似管道的东西,把图像数据通过一系列操作映射成显示用的 view 数据,一般就是 rgb256 数组。你这个操作应该在管道上去搞,换句话说就是 view 层面的东西。
    你还是找个图像库去弄吧。。。
    aheadlead
        18
    aheadlead   32 天前
    我想起了以前有个 skia 库,曾经还跟他斗智斗勇来着
    xupefei
        19
    xupefei   32 天前 via iPhone
    @lithium148 内存复制快还是你的锁快?
    nlzy
        20
    nlzy   32 天前   ❤️ 6
    虽说图像处理一律建议使用现成的库,但是两百万个整数,每个元素仅仅是简单的加减,那这数据量一点都不多,运行时间几分钟肯定是代码写错了。别听楼上说的整什么多线程、SIMD 、GPU,我看还是先把代码写对吧。
    chocovon
        21
    chocovon   32 天前
    @nlzy 确实,200w 个 int 应该是秒算的
    hahasong
        22
    hahasong   32 天前   ❤️ 1
    你不会是在视图线程上算的吧 卡 UI 了
    xiadong1994
        23
    xiadong1994   32 天前 via iPhone
    单纯 200w 个 int 循环一次加减应该还到不了秒级的时间,几十~几百 ms
    mekingname
        24
    mekingname   32 天前 via iPad   ❤️ 1
    图片的 RGB 是通过一个二组数组来储存的,这就提示你,可以使用矩阵运算来加速;但是楼主你却把这个二维数组拉成一个一组的数组,一个一个像素点来运算,速度慢是应该的。图像处理领域需要大量的矩阵运算.需要丰富的线性代数的知识储备。
    mxT52CRuqR6o5
        25
    mxT52CRuqR6o5   32 天前 via Android
    同意楼上的说法,才几百万就算个几分钟是代码就没写对,还没到需要折腾乱七八糟技巧的时候
    across
        26
    across   32 天前
    图片亮度就是统一加 rgb,交给 gpu 做很快( OpenGL ES )。
    但我记得 android 上有一类 api,专门封装了针对图片的 gpu 操作(不是 GPUImage ),忘了叫啥了····
    across
        27
    across   32 天前   ❤️ 1
    搜了下是 import android.graphics.Bitmap;
    一搜就看到了 https://blog.csdn.net/gf771115/article/details/40778091
    BugenZhao
        28
    BugenZhao   32 天前 via iPhone
    Marszm
        29
    Marszm   32 天前   ❤️ 1
    我怀疑他代码,每计算一次加减,就重排列一次数组...所以计算量是 n*200 万次..
    tairan2006
        30
    tairan2006   32 天前
    原地修改的话不可能这么慢
    honeyshine75
        31
    honeyshine75   32 天前
    矩阵计算
    dadachen1997
        32
    dadachen1997   32 天前
    矩阵运算库找找看?
    takato
        33
    takato   31 天前
    对于这个情况比较合理的性能情况应该是多少呢?
    我做了一个小测试,randn 一个 shape 为 7000,1000 的 f32 array 做 sum(axis=1)运算
    numpy 跑了 4.6ms
    rust 手写跑了 6ms,并行化后 2ms
    gpu 性能不能看,运算本身很快,但是把数据扔进 cuda 慢得要死。。。

    比较想知道这样的情形在使用单台 PC 的情况下大概能优化到什么程度?
    ReputationZh
        34
    ReputationZh   31 天前
    real 0m0.023s
    user 0m0.016s
    sys 0m0.000s
    domodomo
        35
    domodomo   25 天前
    time ./test
    ./test 0.02s user 0.00s system 87% cpu 0.022 total

    我的哥,你写的啥程序啊,200 万 int 随机加减,0.022 秒就完成了啊
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2842 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 05:27 · PVG 13:27 · LAX 22:27 · JFK 01:27
    ♥ Do have faith in what you're doing.