同步对实例变量的读/写访问以在iOS中实现高性能?

 wumu 发布于 2023-02-07 13:38

对于iOS,在objective-c中同步对实例变量的读/写访问的最佳方式/最小等待方式是什么?

该变量经常被读取和写入(假设每秒读取和写入1000次).更改立即生效并不重要.读取与另一个读取数据一致并不重要,但写入必须迟早反映在读取获取的数据中.是否有一些允许这样的数据结构?

我想到了这个:

创建两个变量而不是一个变量; 让我们称他们为v[0]v[1].

对于每个v[i],创建一个并发调度队列,用于构建围绕它的读写器锁定机制.我们打电话给他们吧q[i].

现在进行写入操作,只有v[0]写入,坚持锁定机制q[0].

在读取操作中,首先v[1]读取并且仅在某个机会(例如1%)下读取操作在必要时查看v[0]并更新v[1].

以下伪代码说明了这一点:

typedef int VType; // the type of the variable

VType* v; // array of first and second variable
dispatch_queue_t* q; // queues for synchronizing access to v[i]

- (void) setV:(VType)newV {
    [self setV:newV at:0];
}

- (void) setV:(VType)newV at:(int)i {
    dispatch_barrier_async(q[i], ^{
        v[i] = newV;
    });
}

- (VType) getV:(int)i {
    __block VType result;

    dispatch_sync(q[i], ^{
        result = v[i];
    });

    return result;
}

- (VType) getV {
    VType result = [self getV:1];

    if ([self random] < 0.01) {
        VType v0_result = [self getV:0];

        if (v0_result != result) {
            [self setV:v0_result at:1];
            result = v0_result;
        }
    }

    return result;
}

- (float) random {
    // some random number generator - fast, but not necessarily good
}

这有以下好处:

v[0]通常不会被读取操作占用.因此,写操作通常不会阻塞.

在大多数情况下,v[1]不会被写入,因此对此操作的读操作通常不会阻塞.

但是,如果发生许多读操作,最终会将写入的值传播v[0]v[1].可能会错过某些值,但这对我的应用程序无关紧要.

你觉得怎么样,这有用吗?有更好的解决方案吗?

更新:

一些性能基准测试(一次读取和写入一个基准测试,尽可能快地完成1秒,一个读取队列,一个写入队列):

在iOS 4的iPhone 4S上:

runMissingSyncBenchmark: 484759 w/s
runMissingSyncBenchmark: 489558 r/s
runConcurrentQueueRWSyncBenchmark: 2303 w/s
runConcurrentQueueRWSyncBenchmark: 2303 r/s
runAtomicPropertyBenchmark: 460479 w/s
runAtomicPropertyBenchmark: 462145 r/s

在iOS 7的模拟器中:

runMissingSyncBenchmark: 16303208 w/s
runMissingSyncBenchmark: 12239070 r/s
runConcurrentQueueRWSyncBenchmark: 2616 w/s
runConcurrentQueueRWSyncBenchmark: 2615 r/s
runAtomicPropertyBenchmark: 4212703 w/s
runAtomicPropertyBenchmark: 4300656 r/s

到目前为止,原子财产获胜.极大.用a测试了SInt64.

我期望并发队列的方法在性能上与原子属性相似,因为它是r/w-sync机制的标准方法.

当然,runMissingSyncBenchmark有时候会产生一些读数,这些读数表明写入SInt64是中途完成的.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有