COW

iOS 性能优化:优化 App 启动速度

你。 提交于 2020-10-25 12:55:58
Python实战社群 Java实战社群 长按识别下方二维码, 按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群 ▲ 作者:Damonwong,iOS 开发者 来源丨老司机技术周报(ID:LSJCoding) Sessions: https://developer.apple.com/videos/play/wwdc2019/423/ 苹果是一家特别注重用户体验的公司,过去几年一直在优化 App 的启动时间,特别是去年的 WWDC 2019 keynote [1] 上提到,在过去一年苹果开发团队对启动时间提升了 200% 虽然说是提升了 200%,但是有些问题还是没有说清楚,比如: 为什么优化了这么多时间? 作为开发者的我们,我们还可以做哪些针对启动速度的优化? 所以我们今天结合 WWDC2019 - 423 - Optimizing App Launch [2] 聊一下和启动相关的东西 名词解释 先介绍一些和启动相关的名词。 Mach-O Mach-O 是 iOS 系统不同运行时期可执行的文件的文件类型统称。主要分以下三类: Executable - 可执行文件,是 App 中的主要二进制文件 Dylib - 动态库,在其他平台也叫 DSO 或者 DLL Bundle - 苹果平台特有的类型,是无法被连接的 Dylib。只能在运行时通过

(原创)最短路径-Dijkstra算法,以Til the Cows Come Home为例

六月ゝ 毕业季﹏ 提交于 2020-10-18 02:44:10
(1)首先先解释一下单源最短路径: 1)容易的解释: 指定一个点(源点)到其余各个顶点的最短路径,也叫做 “ 单源最短路径 ” 2)官方解释:给定一个带权有向图G=(V,E),其中每条边的权是一个实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到其他所有各顶点的最短路径长度。这里的长度就是指路上各边权之和。这个问题通常称为单源最短路径问题。 ( 2 )解释一下 Dijkstra 算法: 例如求A点到B、C、D、E、F顶点的最短路径; 我们可以先这样设想: 1 )先把所有的点到另一个点的长度全部初始化为无穷大 , 本身到本身则初始化为 0 , 再输入数值; 第一:将所有点到点初始化为无穷大 代码大致如下: 1 const int INF = 0x3f3f3f3f ; // 为无穷大; 2 int G[ 2000 ][ 2000 ]; 3 int N ; // N为点的个数; 4 5 for ( i = 1 ;i <= N ;i++ ) 6 { 7 for ( j = 1 ;j <= N ;j++ ) 8 { 9 G[i][j] = INF; 10 } 11 } 也可用下面这种: 1 #include< string .h> 2 const int INF = 0x3f3f3f3f ; 3 int N; // 点的个数; 4 int G[ 2000 ][ 2000 ]; 5

如何从JavaScript对象中删除键? [重复]

霸气de小男生 提交于 2020-08-20 01:03:01
问题: This question already has an answer here: 这个问题已经在这里有了答案: How do I remove a property from a JavaScript object? 如何从JavaScript对象中删除属性? 41 answers 41个答案 Let's say we have an object with this format: 假设我们有一个具有这种格式的对象: var thisIsObject= { 'Cow' : 'Moo', 'Cat' : 'Meow', 'Dog' : 'Bark' }; I wanted to do a function that removes by key: 我想做一个通过键删除的函数: removeFromObjectByKey('Cow'); 解决方案: 参考一: https://stackoom.com/question/EUuL/如何从JavaScript对象中删除键-重复 参考二: https://oldbug.net/q/EUuL/How-do-I-remove-a-key-from-a-JavaScript-object-duplicate 来源: oschina 链接: https://my.oschina.net/u/4438370/blog/4310856

并发和Read-copy update(RCU)

可紊 提交于 2020-08-18 08:39:22
文章目录 简介 Copy on Write和RCU RCU的流程和API RCU要注意的事项 RCU的java实现 总结 简介 在上一篇文章中的并发和ABA问题的介绍中,我们提到了要解决ABA中的memory reclamation问题,有一个办法就是使用RCU。 详见 ABA问题的本质及其解决办法 ,今天本文将会深入的探讨一下RCU是什么,RCU和COW(Copy-On-Write)之间的关系。 RCU(Read-copy update)是一种同步机制,并在2002年被加入了Linux内核中。它的优点就是可以在更新的过程中,运行多个reader进行读操作。 熟悉锁的朋友应该知道,对于排它锁,同一时间只允许一个操作进行,不管这个操作是读还是写。 对于读写锁,可以允许同时读,但是不能允许同时写,并且这个写锁是排他的,也就是说写的同时是不允许进行读操作的。 RCU可以支持一个写操作和多个读操作同时进行。 更多精彩内容且看: 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新 Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新 Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新 java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程 更多内容请访问 www.flydean

PHP 内核:foreach 是如何工作的(二)

徘徊边缘 提交于 2020-08-18 06:34:31
PHP 内核:foreach 是如何工作的(一) PHP 5 内部数组指针和散列指针 PHP 5 中的数组有一个专用的 “内部数组指针”(IAP),它适当地支持修改:每当删除一个元素时,都会检查 IAP 是否指向该元素。 如果是,则转发到下一个元素。 虽然 foreach 确实使用了 IAP,但还有一个复杂因素:只有一个 IAP,但是一个数组可以是多个 foreach 循环的一部分: // 在这里使用by-ref迭代来确保它真的 // 两个循环中的相同数组而不是副本 foreach ($arr as &$v1) { foreach ($arr as &$v) { // ... } } 为了支持只有一个内部数组指针的两个同时循环,foreach 执行以下 shenanigans:在执行循环体之前,foreach 将备份指向当前元素及其散列的指针到每个 foreachHashPointer。循环体运行后,如果 IAP 仍然存在,IAP 将被设置回该元素。 但是,如果元素已被删除,我们将只在 IAP 当前所在的位置使用。这个计划基本上是可行的,但是你可以从中获得很多奇怪的情况,其中一些我将在下面演示。 数组复制 IAP 是数组的一个可见特性 (通过 current 系列函数公开),因此 IAP 计数的更改是在写时复制语义下的修改。不幸的是,这意味着 foreach

理解PHP垃圾回收机制

让人想犯罪 __ 提交于 2020-08-17 15:51:30
php的垃圾回收机制可以简单总结为 引用计数 写时复制 COW机制。 引用计数基本知识 官网的解答如下 每个php变量存在一个叫”zval”的变量容器中一个zval变量容器,除了包含变量的类型和值 ,还包括两个字节的额外信息 is_ref 和 refcount is_ref 是个bool值,用来标识这个变量是否是属于引用集合(reference set)。 通过这个字节,php引擎才能把普通变量和引用变量区分开来 refcount 用以表示指向这个zval变量容器的变量个数 PHP5 中的引用计数在PHP5中,zval 的内存是单独从堆(heap)中分配的(有少数例外情况),PHP 需要知道哪些 zval 是正在使用的,哪些是需要释放的。所以这就需要用到引用计数:zval 中 refcount__gc 的值用于保存 zval 本身被引用的次数,比如 b = 12语句中,12 被两个变量引用,所以它的引用计数就是 2。如果引用计数变成 0,就意味着这个变量已经没有用了,内存也就可以释放了。 如下: <?php //php zval变量容器 $a = 1 ; $b = 1 ; $c = & $a ; $d = $b ; $e = range ( 0 , 3 ); xdebug_debug_zval ( 'a' ); xdebug_debug_zval ( 'b' ); xdebug

PHP7是如何实现多进程的?

扶醉桌前 提交于 2020-08-17 08:59:10
我们都知道PHP是单进程执行的,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,但PHP实现多进程也意义重大,尤其是在后台Cli模式下处理大量数据或运行后台DEMON守护进程时,多进程的优势不用多说。 要实现PHP的多进程,我们需要两个扩展 pcntl 和 posix,安装方法这里不再赘述。 在php中我们使用pcntl_fork()来创建多进程(在*NIX系统的C语言编程中,已有进程通过调用fork函数来产生新的进程)。fork出来新进程则成为子进程,原进程则成为父进程,子进程拥有父进程的副本。这里要注意: • 子进程与父进程共享程序正文段 • 子进程拥有父进程的数据空间和堆、栈的副本,注意是副本,不是共享 • 父进程和子进程将继续执行fork之后的程序代码 • fork之后,是父进程先执行还是子进程先执行无法确认,取决于系统调度(取决于信仰) 这里说子进程拥有父进程数据空间以及堆、栈的副本,实际上,在大多数的实现中也并不是真正的完全副本。更多是采用了COW(Copy On Write)即写时复制的技术来节约存储空间。简单来说,如果父进程和子进程都不修改这些 数据、堆、栈 的话,那么父进程和子进程则是暂时共享同一份 数据、堆、栈。只有当父进程或者子进程试图对 数据、堆、栈 进行修改的时候,才会产生复制操作,这就叫做写时复制。 在调用完pcntl_fork

LVM : 快照

前提是你 提交于 2020-08-14 22:52:51
LVM 机制还提供了对 LV 做快照的功能,也就是说可以 给文件系统做一个备份 ,这也是设计 LVM 快照的主要目的。LVM 的快照功能采用写时复制技术(Copy-On-Write,COW),这比传统的备份技术的效率要高很多。创建快照时不用停止服务,就可以对数据进行备份。说明:LVM 还支持 thin 类型的快照,但是本文中的快照都是指 COW 类型的快照。 LVM 采用的写时复制,是指当 LVM 快照创建的时候,仅创建到实际数据的 inode 的硬链接(hark-link)而已。只要实际的数据没有改变,快照就只包含指向数据的 inode 的指针,而非数据本身。快照会跟踪原始卷中块的改变,一旦你更改了快照对应的文件或目录,这个时候原始卷上将要改变的数据会在改变之前拷贝到快照预留的空间。 说明:本文的演示环境为 ubuntu 16.04。 LVM 快照的原理 创建快照实际上也是创建了一个逻辑卷,只不过该卷的属性与普通逻辑卷的属性有些不一样。我们可以通过下图来理解快照数据卷(图中的实线框表示快照区域,虚线框表示文件系统): 左图为最初创建的快照数据卷状况,LVM 会预留一个区域 (比如左图的左侧三个 PE 区块) 作为数据存放处。 此时快照数据卷内并没有任何数据,而快照数据卷与源数据卷共享所有的 PE 数据, 因此你会看到快照数据卷的内容与源数据卷中的内容是一模一样的。

使用Apache Hudi构建大规模、事务性数据湖

社会主义新天地 提交于 2020-08-14 20:33:12
一个近期由Hudi PMC & Uber Senior Engineering Manager Nishith Agarwal分享的Talk 关于Nishith Agarwal更详细的介绍,主要从事数据方面的工作,包括摄取标准化,数据湖原语等。 什么是数据湖?数据湖是一个集中式的存储,允许以任意规模存储结构化和非结构化数据。你可以存储原始数据,而不需要先转化为结构化的数据,基于数据湖之上可以运行多种类型的分析,如dashboard、大数据处理的可视化、实时分析、机器学习等。 接着看看对于构建PB级数据湖有哪些关键的要求 第一个要求:增量摄取(CDC) 企业中高价值的数据往往存储在OLTP中,例如下图中,users表包含用户ID,国家/地区,修改时间和其他详细信息,但OLTP系统并未针对大批量分析进行优化,因此可能需要引入数据湖。同时一些企业采用备份在线数据库的方式,并将其存储到数据湖中的方法来摄取数据,但这种方式无法扩展,同时它给上游数据库增加了沉重的负担,也导致数据重写的浪费,因此需要一种增量摄取数据的方法。 第二个要求:Log Event去重 考虑分析大规模时间序列数据的场景,这些事件被写入数据管道,并且数量非常大,可达数十亿,每秒可达百万的量。但流中可能有重复项,可能是由于至少一次(atleast-once)保证,数据管道或客户端失败重试处理等发送了重复的事件

可算是有文章,把Linux零拷贝讲透彻了!

假装没事ソ 提交于 2020-08-13 19:18:41
云栖号资讯:【 点击查看更多行业资讯 】 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 为了迅速建立起零拷贝的概念,我们拿一个常用的场景进行引入。在写一个服务端程序时(Web Server或者文件服务器),文件下载是一个基本功能。 这时候服务端的任务是:将服务端主机磁盘中的文件不做修改地从已连接的 Socket 发出去。 我们通常用下面的代码完成: 基本操作就是循环的从磁盘读入文件内容到缓冲区,再将缓冲区的内容发送到 Socket。但是由于 Linux 的 I/O 操作默认是缓冲 I/O。 这里面主要使用的也就是 Read 和 Write 两个系统调用,我们并不知道操作系统在其中做了什么。实际上在以上 I/O 操作中,发生了多次的数据拷贝。 当应用程序访问某块数据时,操作系统首先会检查,是不是最近访问过此文件,文件内容是否缓存在内核缓冲区。 如果是,操作系统则直接根据 Read 系统调用提供的 buf 地址,将内核缓冲区的内容拷贝到 buf 所指定的用户空间缓冲区中去。 如果不是,操作系统则首先将磁盘上的数据拷贝的内核缓冲区,这一步目前主要依靠 DMA 来传输,然后再把内核缓冲区上的内容拷贝到用户缓冲区中。 接下来,Write 系统调用再把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后 Socket 再把内核缓冲区的内容发送到网卡上。 说了这么多