R之内存管理
引言
R的内存管理机制究竟是什么样子的?最近几日在讲一个分享会,被同学问到这方面的问题,可是到网上去查,终于找到一篇R语言内存管理不过讲的不清不楚的,就拿memory.limit()函数来说,是在windows下才使用的,作者几乎没有提及,还有rm(),gc()函数到底怎么工作的,什么时候用,都无从提及。看来百度是解决不了了,关键时候还是靠google啊,这不,很快找到了一篇相当不错的文章Memory,还是人家外国人比较注重细节,下面的部分几乎是从那儿翻译过来的。需要学习R的高级编程的同学,可以下载Advanced R,本文属于其中的一个章节。另外值得一提的是在R语言实践一书中的附录G对于怎么高效编程,也有一些建议!大数据中怎么使用R,打算下篇博客来写。
目录
- Object size 查看对象在内存中占用的空间大小。
- Memory used & garbage collection 主要介绍mem_used()和mem_changed()函数来阐述R内存的分配和释放的具体工作机制。
- Memory profiling with lineprof 使用lineprof包,对代码运行中内存的分配和释放,以及花费的实践统计分析。
- Modification in place 介绍R对象什么时候才会被拷贝?
准备工作
下面的部分要用到的包为pryr,lineprof,以及ggplot2包中的数据集,因此如果还没有安装的可以运行下面的代码安装:
install.packages("ggplot2")
install.packages("pryr")
devtools::install_github("hadley/lineprof")
1. Object size
这一节用到的第一个重要的函数为pryr包中的object_size(),这个函数返回R对象占用的内存空间。object_size()函数与object.size()相比,能够计算R对象内部共享部分的内存空间以及R对象的上下文环境的大小。下面的代码分别计算了vector,函数,数据集的大小,在R语言中函数也是一个对象。
> library(pryr)
> object_size(:)
#>88 B
> object_size(mean)
#>832 B
> object_size(mtcars)
#>6.74 kB
R对象所占资源内存的分配并不是线性的,例如一个空的向量被分配的资源并不是0,我们做下面的实验:
sizes <- sapply(:, function(n) object_size(seq_len(n)))
plot(:, sizes, xlab = "Length", ylab = "Size (bytes)",
type = "s")
aaarticlea/png;base64,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" alt="" width="418" height="407" />
一个空的R对象分配到的内存空间并不是0,下面的代码充分说明了这一点:
> object_size(numeric())
#>40 B
> object_size(logical())
#>40 B
> object_size(raw())
#>40 B
> object_size(list())
#>40 B
40B大小的空间,到底存了哪些内容?主要分两大部分:
- R空对象数据。
- R对象的元数据(4 Bytes),包括基础的数据类型(例如 integer)和用于调试和内存管理的一些信息数据。
- 两个指针(2*8 Bytes),一个指针指向内存中的前一个对象,另外一个指针指向内存中下一个对象,由于是双指针的,所以使得循环变得简单。
- 一个指针指向attributes(8 Bytes)。
- R向量对象额外的数据。
- 向量的大小信息(4 Bytes),占用4Bytes空间,所能表示的最大的空间为24 × 8 − 1 (231, 大约为2百万),R3.0.0或者以后这个数可能更大,详细可以参见Read R-internals。
- 向量“True”的大小(4 Bytes)。这个数据一般都用不到,但是当向量用作hash表时,那么该值反映的是真正占用的大小。
- 数据块(?? Bytes)。对于空向量,该值为0;另外该值随着数据类型的不同,每个元素占用的长度不同,例如numeric为8 Bytes,integer为4 Bytes,复杂的向量为16 Bytes。
除去向量对象的数据块,我们计算一下空向量占用的大小为(4+2*8+8+4+4=36 Bytes),那么剩下的4 Bytes在哪里?熟悉C语言的人,可能会知道“字节填充”的概念,对于64位系统来说,系统访问内存最好为8 Bytes的边界,否则会访问两次才能访问到数据,造成不能在一个读周期内完全能读取到数据;另外考虑到不同的平台,可能访问规则不同,字节填充有利于平台的移植。如果你感兴趣,可以查阅C structure packing。
上面的部分解释了,空向量占用40 Bytes的原因。那么为什么上面图中向量的占用空间的大小,为什么不是线性的呢?原来是R申请内存空间函数(malloc())是一个非常昂贵的操作,如果每次申请的空间都很小,会导致R比较慢。作为一种替代高效的方法,R每次申请一块空间(小于128 Bytes)作为池子,并自助维护,为了高效和简单,申请的空间大小为8, 16, 32, 48, 64, 或者128 Bytes。如果我们减去空对象占用的40 Bytes的空间,上面的图就会变成下面的那样:
>plot(:, sizes - , xlab = "Length",
+ ylab = "Bytes excluding overhead", type = "s")
> abline(h=,col="green")
> abline(h=c(,,,,,),col="green")
> abline(a=,b=,col="red",lwd=)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoEAAAHJCAIAAAB10nRzAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4Xu2dB3gU1dfGbyolgYQSQuidQEIHASH03qQF0T9FulSlhl5VWqR3kCLKpyCKQgSVIggo0ltC6DX0EAgJkPq9k8WwM9kkm7Bldve9j49PmLlz77m/GXhzyznHLjExUbCQAAmQAAmQAAmYnIC9yXtkhyRAAiRAAiRAAhIBajC/AxIgARIgARIwDwFqsHm4s1cSIAESIAESoAbzGyABEiABEiAB8xCgBpuHO3slARIgARIgAWowvwESIAESIAESMA8BarB5uLNXEiABEiABEqAG8xsgARIgARIgAfMQoAabhzt7JQESIAESIAFqML8BEiABEiABEjAPAWqwebizVxIgARIgARKgBvMbIAESIAESIAHzEKAGm4c7eyUBEiABEiABajC/ARIgARIgARIwDwFqsHm4s1cSIAESIAESoAbzGyABEiABEiAB8xCgBpuHO3slARIgARIgAWowvwESIAESIAESMA8BarB5uLNXEiABEiABEqAG8xsgARIgARIgAfMQoAabhzt7JQESIAESIAFHlSBITEyMjIyMi4vLlSuXnZ2dAa2aNGnSP//8Y8AG2RQJkAAJkAAJKAhkj4vzfvZMc9He3n703Lm5GzRIl5IdxC/dSsarcOPGjeXLl//www9hYWEvXrxAR87OzkWKFOncuXP//v2LFy/+9l3Xrl37ww8/LFeu3Ns3xRZIgARIgARIICUBj7//9l68OMvDh8m3njZu7LZ7d8qaiivmnAcfP37cz8/Pzc2tbdu2Pj4+uXPnxi8ET548CQ0N3bRp08qVK/fu3Vu5cuV0x5BuhRo1atSqVSvdaqxAAiRAAiRAAhkjcO+eGDZMbNmi/RSmti+8vd30aMicGjx8+PDq1asHBQXlyJFDYerLly+7dOkyatSo3Xr8HqHHMFmFBEiABEiABAxKAKvIGzeKESPE48eydkuW/DgxcXD//vn16M2cZ7JOnTrVs2fPlAIMs7NmzdqvX79jx47pMQRWIQESIAESIAHTErhyRTRrJnr2lAmwo6M0Jz59+h9XVz2tMacGlylTZs+ePTo3pHERt7iJq+dbZDUSIAESIAETEYiLEwsXikqVhGKZFjunOP+LWy4u+ltizrXoCRMmdOzY8d69e127dvX19dWciMZ+cEhIyNatW3ft2rVFvsKu/6hYkwRIgARIgAQMT+DkSdGvnzh+XNZy9uxi8mQxapRwcMhoj+bU4A4dOkBoAwMDBwwYoG03fJMaNWqEfeIWLVpkdDysTwIkQAIkQAKGJxAdLaZPF4GBIj5e1jh0avlyUaxY5no0pwbD4uZJJSIiAr5JKFiC9vT0LFSoEM5IZ248fIoESIAESIAEDExg504xcKC4cUPWbK5cYtYs0b//2/RlZg3WmO7u7g4PJUivMWJ0vA0dPksCJEACJGDTBMLDxbhxYtUqJQR/f7F0qfDwUF7P4J/NeSYLpiJGx9ixY0uVKuXi4gIZzpMnD05Ely5dety4cdeuXcvgWFidBEiABEiABAxHAGeSvL2VAozgUbt2ic2b316AYag558Emi9FhuBfClkiABEiABGyAACaBH38sfv9dNlS4Hg0aJD7/XOjtepQuKXNqMGN0pPt6WIEESIAESMCkBOB6hEXmiRPF8+eyfitWFGvWiBo1DGuMOTUYMTrmz5+fRoyO7t276zPakydPzpw5M7WaZ86cuXTpEmNVpsaH10mABEjABgn88ccfq1evVgy8aETEx8ePl8QesHbJlk2MGSPGj0c+A4ODMqcGa2J09O7dO2WipAzF6ChRogQCW+qM9QFeO3bsiMaZchYSIAESIAES+I/AkSNH4uPjEZ1Cc8EhJsb755+99+61V7ge1asn7QeXLWskcubUYEPF6MBhLuRZSg0QNN4h437TqbXG6yRAAiRAAtZBoHz58v443oxy4IDkYhQaKhuXu7uYPVuKyGHQdLoKdObUYMbosI7vmKMgARIgAUslEBEhAgIEFqUVaXyhzUuWiHz5jD0uc2owxsYYHcZ+wWyfBEiABEhAJwHfkBBpkfnBA9ndAgUk9e3QQecjBr9oZg3GeBCXAzGiixUrhmUB7eFFRUVFRkbmz69P9ieDY2GDJEACJEAC1ksgLMz///6vbHCwbIT29qJvXykaZYp0usYDYc4YHdgPnzFjRs6cOXGoCsEpR4wYERsbmzzU5cuXe3l5GW/kbJkESIAESMDmCCQkSGesvL2VAlyhgjh0SKxcaUoBBnxzzoMXLVo0ZcqUoUOH+vn5HTp0CH989OjR119/bXPfBAdMAiRAAiRgAgJnz0pnr5BhULs4OYkRI6R8DEZwPUp3TObU4BUrVgwaNGghsi0KgYPNlSpV6tWrF7IZtm/fPl27WYEESIAESIAE9CXw8qWUXwGRJGJiZI/UrStNi8uV07cdQ9cz51r0nTt3ateunTyijz76qFOnTiNHjnwJWCwkQAIkQAIkYBACBw+KKlXEtGnaAvwqa9ZfmzUT+/ebUYAxOHNqsK+v759//qlNeMGCBeHh4YMHD04t4IZBXgcbIQESIAESsAkCT5+KTz4R9euLCxdk423TZuXQoX+/847AOSyzFnOuRWPZOSAgICEhAR5Kbdu2zZYtG9IXrly58v3330fkLGdzLM2b9V2wcxIgARIgAcMR2L5dSrFw+7asRRz1XbQI25/PPvtMvHpluM4y2ZI5NRjLzs+fP8dRrLVr14aEhHgjRZQQiDoJAR4yZMgDhc9WJgfIx0iABEiABGyMwN27YuhQsXWrbNgId9Wtm1iwQOTOrR4c5tRghJCcPn36xIkTb9++XQBu0f8VBA977733/vrrr6tXr6qHFC0hARIgARJQFYExY8Zcv35d2yQ7IRpfvdr9zJlsWp6uqHDP1XVltWrncdgIGQmTCiZ+ajj/a04N1oDAmjP8g7Uh4mdcbJxUFNf5RxIgARIgARLQEMAa6pw5c5KT77nevVtt1ap8589r80lwcLjYps35Ll3KOznJ4kAJ8Q72g81dzK/B5ibA/kmABEiABCyVABZN8+TJIzDrnTdPTJmi3OJ99137Vau8fXyknU5VFmqwKl8LjSIBEiABEtCTwOHDUuQN+fRXuLiISZPEqFFC3XnzqMF6vmRWIwESIAESUBeBHImJLuPHizVrBCJQapfWrcWyZaJIEXWZq8saM7tG6TKJ10iABEiABEggPQI7dhyMiMiKKFfaAuzpKTZsEDt2WIQAY4TU4PReM++TAAmQAAmoisC9e6JHD9G2bUFt9YXrUffu0oo0bllO4Vq05bwrWkoCJEACNk4gMVFs3CilWHj8WEaiZEmxYoVo0sTi8HAebHGvjAaTAAmQgE0SuHJFNG0qevaUCbCjoxg2TJw+bYkCjLfIebBNfsocNAmQAAlYEIG4OLF0qZgwQURFaVt91tGxyG+/uTVqZEFDUZjKebDlvjtaTgIkQAI2QODkSVGrlvj0U5kAZ8+OXIRN3NziKlWyaATUYIt+fTSeBEiABKyXQHS0GDtW1Kghjh+XDbJlSxEcLAIC4i1/6FyLtvx3yBGQAAmQgPUR2LlTDBwobtyQjQzpFmbOlCJyWEuhBlvLm+Q4SIAESMDSCCBxAtLGK6x2efWqw7//+oWEKK4fL1FiU926zzEnHjBAcytKvj1saaOX7KUGW+Jbo80kQAIkYA0E/v3337Nnz3700UfJgylx/HjdrVuzPn+uPbzIvHn/+t//bpcvX1Y+6Dp16uRWUyLCTLwSanAmoPEREiABEiABwxAoU6ZMf83a8rVrUmLB33+XtQvXo0GDcnz+eStXV8P0p7JWqMEqeyE0hwRIgARsjYDG9WjiRCGf/gqceV69WjqTZb2FGmy975YjIwESIAHVEygcHi7efVccPSqzNFs2MWaM5BDs5KT6EbyVgdTgt8LHh0mABEiABDJJ4MWLytu2dQsKUmY9ql9frFwpyio2fzPZicofo3+wyl8QzSMBEiABaySwf7+oXLnStm0O2nkXcuWS1HffPhsRYLxXarA1ftwcEwmQAAmolsCTJ5JzUcOG4uJFmY3+/uLCBcn3FxmQbKZwLdpmXjUHSgIkQAJmJ7BlixgyRDx4IDOkQAEpHHT79ma3zvQGUINNz5w9kgAJkIDtEbhzR1Lfbdu0R55oZ7e/dOkGx46JHDlsj4g0Ymqwbb53jpoESIAETEUAO75r1ohRo0RkpKzLChV+bd9+y82bDWxVgEGD+8Gm+grZDwmQAAnYIIGzZyXXI2wAawtw1qxiyhRx7NijkiVtEIn2kDkPtvEPgMMnARIgAeMQePkS6QWlFAsxMbIO6taVIm94exunVwtrlRpsYS+M5pIACZCAqgisX7/+As4zy0vx27c77trl8fix9uUXWbLsrlv3cLVqievXa66fO3cub968qhqOiY2hBpsYOLsjARIgAasisHDhwnr16hXA2eakkuXFC7/du6sePmyXmKg9zivlyv3Wvn2km5u71lU/P79GjRpZFY4MDoYanEFgrE4CJEACJCAn0KtXr8qVK0vXtm+Xkv7iCLR28fISixeX7NRpELmlIMAzWSmQ8AIJkAAJkEBGCdy9Kzp3Fu3ayQQY0TYQcwMr1Z06ZbQ9G6nPebCNvGgOkwRIgASMQgBBrfJs3SoWLRLPnsk6KF1aCjyJeFgsqRPgPDh1NrxDAiRAAiSQNoFLl1Zdvlz4s89kAoxkRwEBAl5JFOC06dE/OD0+vE8CJEACJKCLQGysmD1bVKhQXZH0F97Ap05JXklZsuh6jNdkBLgWzQ+CBEiABEgggwQOHxb9+ongYNljOXOK6dPF0KHCnius+vKkButLivVIgARIgASkNedJk8SSJcqkv23aiGXLROHCRJQhAvxtJUO4WJkESIAEbJjAjh3C11c6fqWV9Pexk9PNGTMkryQKcMY/DWpwxpnxCRIgARKwNQL37okePUTbtuLWrTdDh+tR9+6dypYNxySYJVMEqMGZwsaHSIAESMBGCCDc1ddfS9PfjRtlI0a6hT/+wK2njtzTzPynQA3OPDs+SQIkQAJWTuDKFdG0qejZU2hHfobowvXo3DnRuLGVD9/4w+PvL8ZnzB5IgARIQMUEHj9+PH/+/Li4OG0b7RMS/P79t+mhQ47y62GenltbtpRiUU6dqqkfFham4sGp3TRqsNrfEO0jARIgAaMSOH369HfffdcPvkb/Fc+wsJZbt3rKwz7HOjkdbtLkiJ9for19Li2DRo0aVRohsVgyRYAanClsfIgESIAErIhA0aJFA7C8jBIdLfn4Ll0q4uNl42vZ0mn58vpFi9a3olGrYSjUYDW8BdpAAiRAAiog8OuvYtAgceOGzJR8+cTcudKhaBYjEKAGGwEqmyQBEiABiyLgHhMjqazi5DOG4O8vRd7Im9eiRmNJxlKDLelt0VYSIAESMDiBfPv3rz1yRBw8KGu5RAmxYoV0KJrFmASowcaky7ZJgARIQM0Erl4VH3/sCzdf7QLXI6xIf/65cHVVs+3WYRs12DreI0dBAiRAAhkhAI8jHLyaMEFERckeq1RJrF4tatTISFusm3kC1ODMs+OTJEACJGCRBE6fFn37imPHZMZnyyamTBEjRwrGvTLhS6UGmxA2uyIBEiAB8xJ48UJMmyYCAxWuR6fd3SthS7hMGfNaZ4O9U4Nt8KVzyCRAAjZJYP9+0b+/uHhRNvhcuS589NHI06d3U4DN8VEwXrQ5qLNPEiABEjAlgSdPxIABomFDpQDD9ejChbA2bRJNaQz70iLAeTA/BxIgARKwagJbtojBg8XDh7JBFiwoliwR7dtb9cgtYHDUYAt4STSRBEiABNImsHfv3qNHjyrquD150uynn0rIF58T7exO16ixr3XrmNBQMXs2HrmC5EgsZiJADTYTeHZLAiRAAoYjsGDBAmdn51KlSmmatEtMrHH6dJt9+5wRAEur3PPw2Nqixa0CBaS40PgvqeTOnbtJkyaGs4UtZYAANTgDsFiVBEiABFRLoGfPnm3btpXMO3NGIAnSv//KTM2aFUl/848fP9jZWbVDsEHDqME2+NI5ZBIgASsl8PKlmDVLzJwp5NNf4ecnVq0S3t5WOmwLHpZazkUnJiY+e/YsPDwcP1gwTppOAiRAAmYikPv8eVGliuT+qy3A7u5iwQLx558UYDO9lnS6NbMG37hxY+zYsdjDcHFxcXNzy5MnT9asWZEOety4cdeuXUvHdt4mARIgARIAgYiIwWfO1Bk/Ho5GMh5t2ohz58Qnnwh7M/9Tz7eUGgFzrkUfP37cz88P0os9DB8fH5wLwCT4yZMnoaGhmzZtWrlyJU76Va5cOTXTeZ0ESIAESEBs3y4GDmx+544MhZeXWLxYdOpEPionYE4NHj58ePXq1YOCgnLkyKHA9PLlyy5duowaNWr37t0qJ0jzSIAESMA8BO7eFUOGiB9/lPVuZycdyJo7V+TMaR6r2GtGCLzW4Lx6pGh+9OhRRlpOv+6pU6fmz5+fUoDxJFak+/Xr17179/RbYQ0SIAESsDUCODeD7EajR4tnz2RDL11aOnvVoIGt8bDc8b7W4M8++0wzhpiYmMmTJ2N9GNPQAgUKhIWFff/993A7W7RokcEHWaZMmT179vTu3dsOv7jJCxalcatcuXIG75QNkgAJkIBlE8AWL8I+//239iji7e2vdehQ6ttvRZYslj06G7P+tQZ//PHHmoEPHjzY19cX+pflvxc5Y8aMhg0bYsW4VatWhoUzYcKEjh073rt3r2vXrug0V65cEGPsB4eEhGzdunXXrl1bEGKNhQRIgARIQEMgNlbMmydlGHz1SoakTp1hTk4tevYsRQG2tE9FeVju559/xiJwsgBjOFgW7tOnz7Zt2ww+tA4dOkBoHRwcBgwYUKdOnfLly2Pi++677/bt2/fVq1dQfSi0wTtlgyRAAiRgkQQOHRI4ozp2rEyA3dwk16MDB26lOFVjkWO0PaOVZ7KwCHzr1i0Fh5s3bzoaJ6tz86QSERGBRW8U9O7p6VmoUCGckba9d8ERkwAJkIAuAk+fismTpRQLCQmy23A9WrZMFC6s6xleswwCSg1u3br1zJkzvb29MQe1t7dPSEjAgvDcuXN79eplvAG5JxXMg+Pj4+EWHBcXZ7y+2DIJkAAJqJAA/t37+uuvU/7rVxSOv5s2uSL5oFaJzpnz306dLtaqJXbu1FxGrAUVDoompUtAqcHz5s1DDg1/f38cV/by8rp7925kZCSmqoGBgem2ldEKWHNGR2gcD0LsZ82a9cUXX0RFReGPxYsXhyXtmVcro0xZnwRIwDIJXL9+He6aOByTbH7O6OhOR47UunRJe0CII3ikdOnNtWtHOTmJ48eTb9WrV69SpUqWOXSbtlqpwa6urnDJPXDgANJg4bRUwYIFa9WqVbt2bWNA+uqrrzDh1mgwkn7giBZm24jXgZNZP/30E3aL//jjD2bzMAZ5tkkCJKBCAvny5UNsIskwuB5t3CiGDxfh4TI7S5WyW7myVqNGtVRoPU3KFAGlBqMRSGD9pJLcIHaI16xZMw1hSI1WFi9ePHDgwGXY20gqmAHHxsZOnTpVHw3G6g12rFMzjQGoUyPD6yRAAmokcPmyGDBA7N0rsw2z3hEjxNSpOCWrRptpU2YJKDUYa8Lffvvt2bNn8UNymydPnkQ8DeNpMEQU6zDYitYeRYsWLYYgBIwe5Z9//kHSrtQqvnjxAv5Oqd3ldRIgARJQCQFHTH9nz5aEFumPtEvVqlJEDvyfxeoIKDV4ypQpiNdRoUKFCxcueHh44IgytvoROXLFihXGGzsOXSNPg2Iui2PSRYoU0afTunXrYg87tZrY2IbncWp3eZ0ESIAE1EAgy/nzP9y+LbkeaZfs2aUT0aNGCQcHNRhJGwxOQOkfvHHjxkGDBp05c2bp0qUIzXHkyJGrV68irxEyGhm8bzSIc1joBYezcP4L8q852ocpOJyDcRj7dT5qY3TMNkmABEhAJQSioyG9hTt18lFE3kBYpOBgERBAAVbJizKGGUoNxjksTCvRU4MGDf5OioWWPXt2pBfE1qzBu0c8EJzDQsakO3fu4AA2vISx6I1ecCKsTZs2OONnvNVvg4+FDZIACZBAZgj8+qtAUF4sQcfHv3nc01Ns2CCCgkTRoplpk89YDgHlWjQWny8lHYUvWbLk/fv38TNWiREx4/Tp0wYfVLt27bTbhHMwCq4gjvSff/6JtIZwUDZ4p2yQBEiABFRB4P59KekCzj8rir+/FHlDjzw6ygf5ZwskoBQ5HIxauHDhhg0boH/I3YsFYRyKhhMRtNnYo0PQSiSHQC/IFYFT2RRgYwNn+yRAAmYjgGD4vr4KAb6Fw8+//y42b6YAm+29mLxjpQZPnz69UaNGv/zyCyyZM2fO+vXrcTAKobKQucHktrFDEiABErA6AlevimbNRJcuQjsbrKNjRI8erRF1smlTqxswB5QWAeVaNLIWJmcrQvoELEcjWAciaeh5RDmtrniPBEiABGyZAKLwLl0qJkwQSdEA3xRkYli9+pG7+4uWLW0Zj22OXanBGgqIa4FzUjgkhRPRTZs2TZnf1yCwRuHAfXrFGDEy0+uT90mABEjA0AROnRL9+oljx2TtZssmJSLUuB4hNAeL7RHQocHr1q2bNGkSNBg0kMo3ICAAiQVHjx5tcCVGg9hpRgANnPlKzYWXGmx73yRHTAKWSgCHWBHOSGG9Q0xM+S1bym7fbifPevSwfPnjAwZEenmJH3/EI/BJsdRh0+63IKDU4G+++aZ37949evRANgVN+t6aNWtChrNlyzZ06NC36EjHozjw1b9/f+QMHjdunD5zYh1N8BIJkAAJqIYA4t4jbB+cSpIt8nn4sP+xY17Pn2vbGOXs/G2FCntKlEg8eFD7Ov7hVc1QaIiJCCg1GEEzkDhh7dq16F9zMnn8+PE4Gr18+XKDazC6gOMTNN5EY2U3JEACJGBkAn369EGYI6kThMhF0KsffpASMGgXf3+XpUv7e3j0N7IlbN4iCCjPRSMqFgI1K0zHWjTiORtpPEhXnLJHI/XFZkmABEjAFATgelS2rFi1SibAxYqJXbsk1yMPD1PYwD4sgYBSg3EE+tChQwrLEaADcTOMNBykvfSFnxwLCZAACVg+gRyPHwtMY+B69PDhm9Eg3FD//uLsWZGULp2FBJIJKNeiseCMtRTs/nbv3h2no8PDw7EujU0OFFIjARIgARJIlUBCQt3g4M5ffSUUYZ8rVpSyHr3zTqoP8oYNE1BqMDaDnz59ikDNsxG/VAisQru4uOCY9OsdDhsmxaGTAAmQQKoEzpyB69EH//4rqwDXozFjxPjxIikCIAsJpCSg1GDU+PTTT5HIKDg4GEexkM6ofPny7u7uKZ/kFRIgARIgAfHihZRxYeZMERMjo+HnJ+0He3sTEQmkQUCHBqO2q6vrO0kljSd5iwRIgARsncCBA9JGb2iojAMmLVBlROSws7N1Phx/egSUGowNYOTxPXHihCaFkfbj8HtLrzXeJwESIAHbIBARIWX2xUav3PXouq9vMRx+LljQNihwlG9LQKnB/fr12759e9euXfPly/e2bfN5EiABErBKAtu3i4EDRVIwwTelQIHVFSvGtm07iAJslS/dOINSavAff/wxceLEyZMnG6c7tkoCJEAClkwgLEwgYmBSdMk3BWvOWHmeO/fUuHE+ljw42m56AkoN9vDwqF69uuntYI8kQAIkoGoCWHPGyjPyK0RGyuxEeAOcvapdW9XG0zi1ElBqcM+ePZFHAYGrNIEq1Wo27SIBEiABoxD47bffnj17pmja7dataitW5Ll0Sft6goPDxTZtznfpknD7tkBgLCEuX77s48OZsFHei7U2+lqDk9MTIToHzl5VqFChdevWmBNr50piWgVr/Qg4LhIgAQ2BmJgY/NOnSVejueKQkNDm4sWG5887ybMehebNu6JatTtw/N22LZke8q9XrVqVMElAfwKvNXjJkiXJzzg5OUVFRW1GUFN5oQbrj5U1SYAELJEAggM6Ojq++dcPeY3gehQSIhuLm5uYNq3s0KHzEYGShQTejsBrDU5OyYC1FGTzRXm7Zvk0CZAACVgygadPBY6mYnIin/6KNm3EsmWicGFLHhttVxEB5e9xNWrUQCIjFRlIU0iABEjAxATgeoSTVosWyQQ4f34p5RFuUYBN/DqsujulBg8bNuznn39+jNQfLCRAAiRgYwTs7t/fFBsr2rUTOGaVXOB61L27OH9e+PvbGA8O1+gElOeikbuwSJEiFStWbNeuXdGiRbE1kmwC94ON/jbYAQmQgLkIwPVo40bn4cM7KhafS5USK1eKRo3MZRf7tW4CSg0ePXo0Bozj0IiWpRg5Ndi6PwWOjgRsl8Dly2LAALF3r4yAk5MYMUJMnSqyZrVdMhy5kQkoNfi29gqMkftm8yRAAiRgZgJYeZ43T0yZokz6i5gbiMhBZ18zvx7r716pwZoR44D+nTt3IiIiSpUqlSVLFm0vYetHwhGSAAnYCIG//5ZiTGKjV6tEC5F91iwpHpaDg41g4DDNSEB5JgumrFu3rnBSQaQO+Cy1b99+zpw5UGUzWsmuSYAESMCQBKKjxdixAil+5QKc0KJFJYTdQEIkCrAhcbOtVAkoNfibb77p3bt348aNsR+MYB14rmbNmgEBAdpBPFJtjDdIgARIQP0EgoJEuXJSit/4+DfGenqKDRtit227xaS/6n+DVmShci161qxZvXr1Wrt2LcaoCRk9fvz4W7duLV++fCiyhbCQAAmQgOUSuH9f4Njpxo3KEcDpCJE38uZV7gor6/HPJGBgAkoNvnr1asrEhXXq1NmwYYOBezZVcwllEkIKhuwWu03VIfuxQgLh4eHJseSscHi2MKTERJ+gE43m7cj2FBu+b0pEwdy/Teh4o2ZpcXOtuCni4uISGiXwnwtb+CKMOsbnNZ4niAR9ukQO5KgAACAASURBVFBqMPyDDx061KVLF+2HT58+XaZMGX2aU2GduM5xOyvuPCPOqNA2mmQpBC4+uvjo5aOs9FGxlBcmt7PYnYR5n0fVPxKrfTnOQaz1zzpjSGJ0Nq1kwI4iz5w8s8VsyxworVYLgYe9Hj5zUGbf0mmcUoOx4NynTx9kT+revTvOYeHXf6xLL0gqOp9X/0XnL5xHeIzo27ev+k2lhaol8MnST0qWLIkocqq1kIbpJhAXJ5YuFRMmiCiZAIvKlR1Xr+5fvXp/3Y/xKgm8FYFKgyq5b3TXpwmlBmMz+OnTp9OmTZuNAwtCYBXaxcVl0qRJgwYN0qc51iEBEiABtRA4dUpyPTp2TGZP9uxSMga6HqnlJdm6HUoNBo9PP/0Us8bg4GAcxfLy8ipfvry7u156bussOX4SIAGVEIDr0fTpIjBQdvIZtjVoIFatEqVLq8RMmkECSg3u379/t27d6tat+05SISASIAESsDACu3aJgQPF9esys3PlEoi8gWTALCSgJgJK/+CgoKD69esXK1Zs3Lhx586dU5OptIUESIAE0iTw5IkU9rllS6UAw/UoNJQCnCY73jQPAaUGY/358OHDOBf9/fffI05W5cqVAwMDGUTaPC+HvZIACehPYMsWUbastNSsXYoXF5gWI++vh4f+LbEmCZiMgFKDEZejdu3a0N0rV66cOHGiTZs2X331FbIZNmLqLpO9E3ZEAiSQIQLXrokWLQQ8Kh8+fPOcvb008T1zRjRvnqHGWJkETElAqcHJfSNPA1akcSALuYQRtPLAgQOmNIt9kQAJkED6BOB6tHChqFhR/PabrDKuIB8D8v66uqbfCGuQgPkI6NBgxANavHhxkyZN8uXL99FHH0VGRiJQ5X3EeGMhARIgAfUQwBy3Th04cojnz98YlS2blIjw6FHBI6XqeVO0JHUCynPR2ABGVCxnZ+fmzZtjFbpt27a5cJ6QhQRIgATUQ+DFCynjwsyZIiZGZlS9etJ+MHaFWUjAQggoNbhEiRJjxozBNnDOnDktZAg0kwRIwJYIYF8MG70456xdEMMAqoyIHMx6ZEvfghWMVanBP/74OnTqq1ev7t275+npyRi5VvCaOQQSsAYCERFSZt/Vq4UinXmbNmLFClGwoDWMkWOwMQI69oN//vnnKlWqIGQ0zmRlz569UqVKv/zyi41h4XBJgARURmD7duHjIy01awtwgQIC0wbcogCr7HXRHD0JKDUYAty+ffv8+fOvW7fu999/R8pChKt87733ELtDzxZZjQRIgAQMSSAsTHTsKNq1E/ghuWDNGSvSFy6IDh0M2RfbIgHTElCuRX/++ecffPDBt99+C98kjSUIXenv7z9jxozWrVub1jb2RgIkYNsEEhLEmjVSfoXISBkIX19pRbpWLdumw9FbAwHlPBipGjDrTRZgDBE/Y2Z8/vx5axgux0ACJGApBBArF65HiD2pLcBOTtKWMFIhUYAt5T3SzjQJKDW4cOHCKcNEnz17FqGy0myHN0mABEjAQARiY6VDztWqiX/+kbUIST59Wkq9kCWLgXpiMyRgZgLKtej//e9/SB6MZIX4ATE6EJoD69JffvnldCQCYyEBEiABYxM4eFDa6A0JkfXj5iamTRNDhwpEoGQhASsioNRgpEuC7o4dO3bUqFFYhU5MTHR0dBw0aFAA1n9YSIAESMB4BJ4+FZMniyVLBLaBtQtcj5YvF4UKGa9ntkwC5iKg1GAHBwcEqoQGI1pWWFhYgQIF4JtUkOf+zfV+2C8J2AgB+BcNGiRu35YN18tLLFokOne2EQYcpg0SUGqwBgFEl7prg18Dh0wCZiBw964YNkz88IOsa/hldOsmFiwQuXObwSR2SQKmIqBbg03VO/shARKwYQKItrFxoxg+XISHyyiUKiXF4mjY0IbRcOi2QoAHHGzlTXOcJKAuApcvi8aNRc+eMgHWuB7BK4kCrK63RWuMRYDzYGORZbskQAK6CcD1aN48KcPgq1eyCrVrS5E3EJCShQRshgA12GZeNQdKAmogcPiw5HqkiPmTPbt0IhrxsBwc1GAjbSABkxFQarAvgsClKHBSgsewh4dHxYoVBwwYgAjSKarwAgmQAAmkSSAqSsyYIQIDRXy8rB6C4C5bJhgFKE14vGmtBJT7wXAFfv78+e3bt318fBo3blyhQoU7d+4gjyEyKSGJ4apVq0qWLHnmzBlrxcFxkQAJGIUAkr6ULy9Fv9IWYE9PsWGD2LGDAmwU5mzUEggo58FQXMx3obI5c+bU2P/s2bNGjRphfty/f/+4uLiOHTsifAdSKlnC6GgjCZCAuQncvy9Gj5bOP2sXjevR/PkiTx5z28f+ScCcBJTz4I0bNw4bNixZgGEafh48ePA8nKEQAjGzcPfEiRPmNJl9kwAJWAQBuB59/bV0xkohwCVLCvwSj1sUYIt4jzTSmASUGoy+Hjx4oOgR0SufIoxcUomMjHSC/wALCZAACaRB4MoV0ayZ5Hr0+PGbWo6OUjgO5F1o0iSNR3mLBGyHgFKDO3fujJwNW7dujU/atsH/f/jhByQVRgrh2NjYPXv2YCG6ZcuWtgOIIyUBEsgYgbg4sXChqFRJ7N4te7ByZSkPEm65uGSsQdYmAesloNwPnjVrFubBUGJnZ2dsDD98+DAmJgb5g3E9NDS0SZMmTZs2nTNnjsGBIDkEZtjYb86VK5d29mKDd8QGSYAEjEjg5EnRr584flzWBV2PjEicTVs2AaUGQ3q/+eabCRMmHD58+NatW3BDqlGjRtWqVTHK4sWL37hxw7CJhNHg8uXLMdVGfogXL16gFxiALvBLAI6AoUfLpkvrScB2CERHC2Q4Tel61KKFlPWoWDHbIcGRkoD+BJQarHmyXFJRtOKSVPRvOt2ax48f9/Pzc3Nza9u2LVyhcufOjdnwkydPMOHetGnTypUr9+7dWxnrVywkQAIqJ7Bzpxg4UNy4ITMT6RZmzpQicrCQAAmkQkCpweHh4ZMmTTp27JhmP1j7KVxMpZFMXh4+fHj16tWDgoJy5MihaOLly5ddunTB3vNuxZZSJrviYyRAAsYhgHQL48ZJKRYUxd9fLF0qPDyU1/lnEiABLQJKDcYK8I4dOz744ANPuM8buZw6dWr+/PkpBRjdIh5Iv379unfvbmQT2DwJkMBbENiyRQweLB4+lDWBLaQVK6RD0SwkQALpEVBqMIJvfPnll3AITu9BA9wvU6YMDlr37t075SEsLErjVsr1cAP0yiZIgATensC1a+LjjyU3X+0C16NBg8TnnwtX17fvgS2QgC0QUGpwwYIFS5QoYZqR4+QXom7du3eva9euiMOlORGN/eCQkBA4R+3atWsLfstmIQESUBUBuB5hkXniRPH8ucyuihXFmjWiRg1VGUtjSEDlBJQajFkpgkI3a9bMwfgJTDp06AChDQwMRB4IbUyYFiM6JvaJW+BEJQsJkIB6CCC8BlyPjh6VWZQtmxgzRowfD68G9VhKS0jAIggoNRjOSPAPxinlVq1awT9Ye5V47NixBh9S86QSEREB3yQULEFjH7pQoUI4I23wvtggCZBA5gnAdRAZF774QiD7r3apV086kFW2bOZb5pMkYMMElBo8EUtMSeXHH39UYDGGBmu6QGJEeChBehmjw4Y/RQ5dxQQOHJBcjEJDZSa6u0uqjGkxEjCwkAAJZIqAUoOvX7+eqXYy+RBjdGQSHB8jAdMQiIgQAQFi9WqBBAzaBa5HS5aIfPlMYwV7IQFrJaDUYFOOkzE6TEmbfZFAhgngUOSQIcjiInuwQAFJfTt0yHBrfIAESCAFgdcavGLFigIFCrRr1w4/pKjz+sLHcEUwaGGMDoPiZGMkYDgCYWGS+v70k6xFe3vRt68UjTJFUB3DdcyWSMC2CLzWYOz11q1bFxqcvB+cEoPBNdhQMTqCg4MXIhlLKuXVq1fPFU4UqdTkZRIgAZGQILkYjRqFNKUyGhUqSGevatUiIhIgAQMSeK3BOJmsafTRo0cGbD3tpgwVoyNPnjzVqlVLra8NGzZkyZIltbu8TgIk8IbA2bPSGasjR2RMsmaVtoTpesQPhQSMQMCc+8GGitEBdyaE2EwNzsiRI52cnFK7y+skQAISgZcvxaxZUoqFmBgZkLp1pelvigwuhEYCJGAQAq81OG/evOk2Z/ApMmN0pMucFUjAFAQOHpSmvxcuyPpycxPTpomhQwW2gVlIgASMQ+C1Bn/22Wea9mNiYiZPngxvXaQtwiktxM34/vvvkdN30aJFxjCAMTqMQZVtkoC+BJ4+FZMnS+ecsQ2sXdq0kZL+FiqkbzusRwIkkCkCrzU4+bwVsjUgdDPyJSTvoc6YMaNhw4aIHInIWZnqIv2HEKMDpXz58ulXZQ0SIAFDEdi+XUqxcPu2rD0vL4FfuDt3NlQnbIcESCANAspVpp9//hlJA7UPMSGNYJ8+fbZt25ZGK7xFAiRgSQTu3pVUtl07mQAj3BWyhZ47RwG2pFdJWy2cgPJMFiI237p1SzGomzdvOiIrGQsJkIClE0C4KwS9Gj1aPHsmG0rp0mLlStGwoaWPj/aTgGURUCpr69atZ86c6e3tjayC9vb2CQkJSCA4d+7cXr16GXxgo+CDmF5BVqX0qvA+CZCAfgQuXRLIUbZvn6w2vAZGjJCOX9GFTz+KrEUCBiSg1OB58+ZduXLF398/R44cyKF09+7dyMhInJwyhhYiKdNXX32FhMHIkoTkwTpHZYx+dXbEiyRgzQSQ7GjePDFlinj1SjbMd9+VXI98fKx57BwbCaiYgFKDXV1dd+/efeDAgaNHj967d69gwYK1atWqXbu2MYaA6TX8esuVKzdu3Dh95sTGsIFtkoD1Ezh8WHI9Cg6WjdTFRUyaJMXDMn6mcOsnzBGSQGYJKDUY7WB6Wj+pZLbNDDxXunTpmjVrZuABViUBEtCfADZ9IbQpXY9atxbLlokiRfRviTVJgASMQUCpwS1atEitm127dqV2622uY/sZa9Fv0wKfJQES0EFgxw7J9UhxxNLTU8yZI3r00FGfl0iABExOQKnBhbS88nFG+v79+wcPHsTFrl27Gsm2evXqGallNksCNkrg3j0xZozYuFE2fLgedesm5s8XefLYKBYOmwTUR0CpwWuQMkVekM6hZcuWOJ+lPuNpEQmQgJwAXI8gvTjn/Pix7EbJkpLrUePG5EUCJKAqAsoYHSmNQwSrgICAxYsXp7zFKyRAAioicOWKaNpU9OwpE2B49g8bJk6fpgCr6E3RFBL4j4ByHqyTTFRU1OXLl3Xe4kUSIAHzE4iLE19+KaZOldIfaZcqVaSIHKln9jS/5bSABGybgFKD169frwDy8OHDL7/88p133rFtUBw9CaiVwMmTom9fceKEzL7s2aVkDHQ9UutLo10koCGg1OAhQ4Yo0Dg4OFSuXHnFihVERgIkoC4C0dFi+nSBWHLx8TLDWraUsh4VLaoua2kNCZBACgJKDX7+/HmKOrxAAiSgPgI7d4qBA8WNGzLL4OY3c6bo31995tIiEiABHQTSP5Ol4yFeIgESMCOB8HAp7DNyiSoE2N9fhIZSgM34Ztg1CWSUwOt58IIFC9J98tNPP023DiuQAAkYl8CWLVLkjUePZL0ULy6wW9SsmXG7ZuskQAKGJvBag2fNmpVuy9TgdBGxAgkYkcC1a+Ljj8Xvv8u6gOsRJPnzz4WrqxG7ZtMkQALGIfBag5GewTjts1USIIG3JgDXo6VLxcSJQnFco1IlyfWoRo237oANkAAJmIeAjv3gW7duLVq0CD7BsCgkJATZDMPCwsxjHXslARJAeA1kGMROkLYAZ8smJSI8epQCzA+EBCyagFKDz549i2SC48ePj4mJwcCgxDNmzPDx8Tl+/LhFj5PGk4DlEXjxQgq7gWkutFa7IKfZqVPSLScnyxsULSYBEtAioNTgkSNH1qhRA0vTuXLlQrXq1atjWlypUqUxCAHPQgIkYDIC+/eLypXFtGkiNvZNn/hbibDP+/aJMmVMZgg7IgESMB4BpQYfPXp04MCBrlrnO/Bz//79jx07Zjwj2DIJkMAbAk+eSK5HDRuKixdlWOB6dOGC5HqEDEgsJEACVkFAGaPDw8Pj+vXriqFdu3YtX758VjFeDoIE1E0ArkeIVffggczKAgWkM1nt26vbdFpHAiSQYQLKefAHH3wwffr0b7/99tWrV2gsNjb2u+++mzlzZqdOnTLcNh8gARLQn8CdO6JDB9Gli0yA7e2liS+mvxRg/UmyJglYDgHlPHjSpEnYDO7Ro0f37t1z58795MmThISEDz/8EMJsOYOipSRgUQQSEgTydiO/QmSkzO4KFSTXo5o1LWowNJYESCADBJQa7OjouHLlSpzA+ueff3Aay8vLC8eycC46A02yKgmQgP4Ezp4V/fqJI0dkT2TNKgICxPjxwtlZ/5ZYkwRIwOIIKDX49OnTOAVdMqloD2bv3r2NGjWyuOHRYBJQLwHk+kV8OqRYSPIDfFP8/MSqVcLbW72W0zISIAEDEVDuB2PWO3nyZM1msKaLBw8eYGm6cePGBuqRzZAACQjx11+iShXJ9UhbgN3dBSK3//knBZifCAnYCAGlBv/f//3fV199hYTBhw8fxk7wmjVrvL29Dx06FBQUZCNEOEwSMC6BiAjxySeiQQPppJV2adNGYF0at3AOi4UESMA2CCj/tnfu3BnxKZs3b16/fn1sAw8ZMmTo0KHnzp1rhURpLCRAAm9JYPt24esrFi0SOIeVXLy8xA8/CNwqVOgtm+fjJEAClkVAqcGw3tnZGUGy7O3tHz165O7u7uvrmxUnRFhIgATehsDdu6JzZ9GunYAPUnJBtA2N6xF9/96GLZ8lAYsloNTg3bt3V6xYcenSpevWrUOqBuQrhJNSy5YtL1++bLFjpOEkYFYCiYmvz1ht3Sqzo3RpsWePFHsyZ06z2sfOSYAEzEZAqcFNmzb18/O7cOECfIKdnJzGjh2Lk9LR0dGYDZvNRnZMApZL4NIlAYcCxJ589uzNIJBrAa5H2P1FQEoWEiABGyag9E3at29fA5wW0Sply5b9888/V6xYYcOUOHQSyDgB5FqYN0/KMJgUcu5NQSJCRN4oXz7jLfIJEiABayOg1GCNACcmJt65cyciIqJUqVJZsmTB3vCgQYOsbegcDwkYj8ChQ9JGb3CwrAesOSPe3NChPPlsPPBsmQQsi4ByLRrWYye4cFKpUKEC8je0b99+zpw5UGXLGhitJQHzEHj6VPIvqldPKcBwPTp3jq5H5nkp7JUE1EpAqcHffPNN7969EZFj+/bt2A+G2TVr1gwICFiyZIlah0C7SEA1BHbsEAjyrHA9yp9fbNgguR4VLqwaQ2kICZCAKggo16JnzZrVq1evtWvXwjosQeP/48ePR+Do5cuXw1FYFSbTCBJQIYF798SYMWLjRplpcD3q1k3Mny/y5FGhyTSJBEjA7ASU8+CrV6+2aNFCYVadOnVSJhU2u+k0gARUQQDbNF9/LUXeUAgwIq7/8Yd0iwKsivdEI0hAjQSUGqyJTKmwFO5JZcqUUaP5tIkEzEvgyhXRtKno2VM8fvzGEEdHyfUIu7+Msm7et8PeSUD1BJRr0Vhw7tOnT7Zs2RCaA+ewwsPDsS69IKmofiw0kARMSCAuTnz5pZg6VSD9kXZBJgYkA65a1YSmsCsSIAFLJaDUYGwGP336dNq0abNnz8aYsArt4uIyadIk+iZZ6hum3cYgcOKElPQX/9cu2bOLyZPFqFHCwcEYfbJNEiAB6yOg1GCMEPEp+/btGxwcjKNYXl5e5cuXR9Ro6xs5R0QCmSEQHS35+AYGivh42eNIarJsmShaNDNt8hkSIAFbJaBDg4HC1dX1naRiq1g4bhLQReDXXwWC1dy4IbuXL5+YO1f06KHrAV4jARIggbQI6NbgtJ7gPRKwPQI5oqObffONOHpUOXR/f2n6mzev8jr/TAIkQAJ6EKAG6wGJVWycwJYt47791uXFCxmGEiUEgqjjUDQLCZAACWSWgNI3KbPt8DkSsEYCV6+KZs1Ely4yAYbr0bBh4vRpCrA1vnKOiQRMSkC3BidHh7548eLOnTsfa/s+mtQ8dkYCZiIA16OFC0XFilKcDe1SqZI4fFi65epqJsvYLQmQgPUQUGrwzZs3mzRpMmTIEAwRIaPLlSvXqlUrpC88deqU9QyaIyGBtAlgjlu7NjwERFRUcsU4hE+fNUscOyZq1Ej7ad4lARIgAT0JKDV42LBhoaGhrVu3xvPTp09v167dlStXkMFw4sSJerbIaiRgwQSw6Tt2rKhWTdJarXK5YMFNCAeN6FdYiGYhARIgAQMRUGrwgQMHRo4cibnvgwcPjh07NmbMmBIlSvzvf/87cuSIgXpkMySgVgL794vKlQWi02j7/ubKJVauXNKpUwR8kFhIgARIwKAElBqckJCAwFjo4o8//siZM2eNpGU3/PBSEZDPoEawMRIwM4EnT8SAAaJhQ3HxoswSuB6Fhor+/Zk928wviN2TgJUSUC6sQXTXrVuH2FiBgYGYDTs6OiJa1qpVq3DFSglwWDZPYMsWMXiwePhQBqJYMbF8uUiRQ8zmYREACZCAIQnYJR+B1rR68uTJZs2aPXr0CHPfgwcPVqhQIX/+/Igg/dNPP6XMaWhIQ4zWlvNaZ3d/9xw5chitBzZsIgLPnz9/ggmr4UrR24lLx8U32y+b5SbYi7Vd7QMmOkRqHXyOj4/PnTs3/lIYrnO2RAIkYLUEbt+8/fvz3+uXr5/uCJUajAeioqJCQkKKFy+eJynv6ebNmzE5xh/TbUudFVwLuE6YP+H9999Xp3m0Sn8Cq1evRh7rjz/+WP9HUq2ZkOD1XVDJGcscomSRN6K8S1ycPfpZlXKKB+3s7BA73YHJGFIFyhskQAJvCLRp0ua7ed9VhHNjekW5Fo362A+uVq3anTt3zp07hxPR/v7++AcovXbUe98u0s4j0qOEKKFeE2mZfgRyR+SOj42vXzj9Xy3Tae/MGSnr0b//yqplzYpjzy7jx1dxdk7ncd4mARIggTQJOD10SvP+m5vKM1m4g/3gwkkFC9GYdrRv337OnDmKJWs9W2c1ElAXARwtnDpVcvBVCLCfnzh5UrpFAVbXC6M1JGDlBJQa/M033/Tu3btx48YI0OGEoARC1KxZMyAgYMmSJVZOgsOzegJ//SWqVBHTpomYmDdjRV7OBQvEn38Kb2+rB8ABkgAJqI2Aci161qxZvXr1Wrt2LQy1t5cUevz48TgavXz58qFDh6rNetpDAnoRiIiQwmusXi0S5U5GbdpIeRcKFtSrEVYiARIgAUMTUM6Dr169mvL8c506dbAobeiu2R4JmITA9u3C11esWiUTYC8vsXUrwrFSgE3yDtgJCZCAbgJKDfb29j506JCi7unTp8uUKaO7AV4lAdUSCAsTnTqJdu3EnTtvbMQBw/79xYULomNH1RpOw0iABGyEgHItGgvOffr0yZYtW/fu3XEOKzw8HOvSC5KKjRDhMK2BANacsfI8erR49kw2nNKlpQlxgwbWMEaOgQRIwPIJKDUYm8GIyDFt2rTZiJorBFah4ao0adKkQYMGWf5gOQLbIHDunDTT/ftv2WhxwHDECOlAVpYstkGBoyQBErAAAkoNjoiIwFS4b9++wcHBOIqFuASIUgkZfvbsmZubmwUMiCbaMoHYWDFvnpgyRbx6JcNQp440/WW8VVv+Njh2ElAlAaUG58qV69KlSwjN8U5S0di8Z8+eDh06QIZVOQQaRQJJBHCOAdPf4GAZDvziiLkvjvQnHfJnIQESIAFVEXitwd8lFY1liAXo6qoVKlfgn7VgDw8PVdlNY0jgDYGnT8XkyQIu7AkJMixwPVq2TBQuTFYkQAIkoE4CrzXY2dk5WXex8qzQ4Fq1ajHesjrfH62S/IuQ9ejWLRmK/PmlNMA9epAPCZAACaiZwGsN7phUYOjly5cREguBKk1sNM5gR0ZGxsXFYTHcosNTm5ibTXd3754YNkwg86B2getRt25S6KvcuW0aDgdPAiRgCQSUm2TvvffeK8V5FmMO48aNG2PHjsX2MybfOPOFTE1Zs2YtXbr0uHHjrl27Zsye2bYlE4Dr0ddfCx8fpQCXKiV275ZuUYAt+fXSdhKwHQLKM1lwSUJwyqpVq3bp0qVz584lS5Y0Hovjx4/7+flBetu2bevj44P8rJgNI0FsaGjopk2bVq5cuXfv3sqVKxvPALZskQQuXxYDBoi9e2XGa1yPpk4VSH/EQgIkQAIWQkCpwQ8ePIDybd269csvv8QMFUkMNWJcokQJg49o+PDh1atXDwoKypEjh6Lxly9fot9Ro0btxrSGhQSSCNjHxzc4ckQsXiyQ/ki7VK0qReTA/1lIgARIwKIIKNeicTgL8aKRLP3u3bv79u179913Fy9ejNlwjRo15s6da9j14VOnTvXs2TOlAAMgVqT79et37Ngxi4JJY41J4MSJbkuWtDpwQCbA2bOLWbOkRIQUYGOyZ9skQAJGIqDU4ORuHBwcypYtW6lSJaxL45AU1o0///xzzIYbNmx48eJFg1iDGNTwPNaZmRgXcatcuXIG6YiNWDaB6Ggxdqx45x1P7bDPGFKrVpI3MBIiOThY9gBpPQmQgK0SUK5FQ/xOnjy5Y8cO5A/GNBTz0aZNm2Ja3KZNGxyY+v3330eMGAEHYqxXvz2xCRMm4DD2vXv3unbt6uvrqzkRjf3gkJAQLIbv2rVri+LI69t3yRYsjsCvv4qBA8XNmzLDPT3FnDl0PbK4l0mDSYAEFASUGlywYEGsQiMiB0R34sSJEODsWO77r7Rq1QpRtGbMmGEQjoi9BaENDAwcgCM2WgXT7kaNGmGfOGUWRYP0y0Ysg8D9+1LShY0bldb6+0uRN/LmVV7nn0mABEjA0ggoNRjpktq1a4egHFiL1jkWTwit8QAAIABJREFUVNB4Euu8m9GLzZMKglSHJRXMwj09PQsVKoQz0vo3hafQgv71WdMCCGAJBGlCHj3SNjUid+4tjRv327zZAuyniSRAAiSgBwGlBmvSJaXxINQxQwKZRlPJt9yTCpJDxMfH49gXInXo81Rynf3796fxa0FUVBTWtzPUICubk8DVq5LrkeI8vKMjJHl9vnxhCEvJQgIkQALWQuDNmSwsQW/YsOHXX3+NxhEYITZv3lyhQgXILebE33//vc6TU28JAdmZfvvtN00jCQkJX3zxBXyFEaADU2Ec/tq2bZue7Tdo0AB5jlMriP6BnWY9m2I1cxLA714LF4qKFZUCDB9xJCJcuDDW2dmc5rFvEiABEjA0gdcafOLECUTJ+Oijj1q3bg1/pJ07d+KcVN68eXv06AH1xc9fI/aQoctXX3119uxZTasLFizAES34BP/4448//fQTYndgt5jOwYZGruL2Tp0StWuLTz8VUVFvrMyWTXI9gota9eoqNp2mkQAJkEAmCdhpJriNGzdGpGicRsYcdNCgQdBgTFJXrFiBVlGhffv2uHv+/PlMdpLKYzh7BZ9jBOLA/eLFi7ds2XIZztr8Vz788MObN28ePHgwlaf1vey8yLnAhwXw+4S+D7BemgSwto/3kmaVjN3M9lKMXxb7ybpYh3jZg3/VsB86LculYnbJV7FJgYUZHBvMWAesTQIkQAKmJRByNuRXh1/rl6+fbrev94MxDw4ICEDUKjzw2WefwTcJ56I1D0MpoY5DkYHVaAX/tl6/fh1TcO0ecCh6yJAhb9+n8zLn7kW649eIt2+KLYDA74d+/+WXXwYjVZEhiue/IbWmrM1x4552YzE5XU6OeP+Gf4NRSMCgXRxFYbfCrkKWWNMQVrANEiABEjAkgQ9nfOg+0V2fFl9rMM4V58uXT/OAl5cXfoBncPLz+Dmj56T06Tu5jqOjI7aBFbMrHJMuUqRIhtrRWdnujl3RR0WriWo67/JiRglcCr9U7HGxbuW6ZfRBZX0clEPkDcSYRAIG7eLv77x0aU0Pj5rKB/hnEiABErAMAllDs9oJ+RQiFcPfnMmyt3/9c/IPqTxiyMuzZs1C4C2se0P4p0yZgjRKaB3ns+AcjGVq5HIwZGdsSz0E4HpUtqxYtUomwMWKiV27cBpQeHiox1JaQgIkQALGI6D0TTJeTylb/vnnn6/8V3AqG3NxhOgqWrTogQMHsBIObZ42bVrKp3jFsgkgJSXiXv13Hv71WPD7X9++4ssvhSvXmS379dJ6EiCBDBF4o8GYkq5fvx4Px8bG4v8jR45MdulBOMkMNapnZQQD0a4J52AUXEEc6T///BNHo005I9fTZlbLPIGEBLFmDT4s8fy5rBE4I2FF+p13Mt8ynyQBEiAByyTwWoNxLjrZfuzOav8R1xG4CsXYA0RkLk1wrgJJxdjdsX2TEjhzRvTrJyU40i5wPRozRowfL+j4a9KXwc5IgATUQuC1BtMTVy0vxPrsePFCzJ4tZs4UMTGywfn5SfvB3t7WN2KOiARIgAT0JGDO/WA9TWQ1CyaAdL/9+4vQUNkQ3N0lVca0WOF6ZMHjpOkkQAIkkBkC1ODMUOMz6RNAFg1k9k3pegS/c8R+YZyN9AmyBgmQgPUToAZb/zs2wwi3b5cOP9+5I+sae/yLF4uOHc1gD7skARIgAVUSeOMfrErzaJSlEQgLE506CZx41xZgrDljRfrCBQqwpb1O2ksCJGBcApwHG5evDbWOcFdYeUb078hI2ah9faXrtWrZEAoOlQRIgAT0I8B5sH6cWCttAufOiXfflfL+aguwk5O0JYysRxTgtOnxLgmQgK0S4DzYVt+8ocaNiC7z5okpU8SrV7Im69SRpr/lyhmqH7ZDAiRAAtZHgBpsfe/UhCNCZkls9IaEyLp0cxMIMopEW/9FIDehQeyKBEiABCyJADXYkt6Wimx9+lRMniyWLEGGDZlVcD1CEujChVVkKk0hARIgAbUSoAar9c2o2K6qOPOMk1a3b8tszJ9fLFok/P1VbDhNIwESIAF1EaAGq+t9qN2ae/fqLFhQ+MgRmZ1wPerWTSxYIHLnVrv9tI8ESIAE1ESA56LV9DbUbAtcj77+Wvj4KAW4VCmxe7d0iwKs5tdH20iABFRJgBqsyteiNqMuXxbIrNWzpwgPf2OaxvUIXkmNGqnNXtpDAiRAAhZBgGvRFvGazGdkaq5HtWtLrkc+PuazjD2TAAmQgMUToAZb/Cs04gD+/lvKbnT+vHYX8VmybPb2/uCvv4SDgxG7ZtMkQAIkYAMEuBZtAy85E0OMjhZjxwqk+JULsGjVKigw8BdE3qAAZ4IqHyEBEiABOQFqML+IFASCgqT4VkjxGx//5p6np9iwQQQFRefNm+IBXiABEiABEsgMAWpwZqhZ7TP374sePQTibNy8+WaMcD3q3l3g7BVusZAACZAACRiOgF0ifE6sumT5LEvJXiULWlfS+FevXgUHBxvw3dklii5Brz6bF537qex7uF7QfsQEl/01nZK/kZiYGFdXV1/E6GAhARIgARLQReDfA//uyLPDz8dP103ZNes/k+W4zbFltZYtC7ZMl4UFVTh/+fytZbcGDhxoEJvdbz9u/sVPRY9c0m4twcH+pH/tA0Na1MrmLMs76CwK5C2QX+Q3SNdshARIgASsj8CAjQNyDMuhz7isX4PtQ+3L3SnXRDTRB4el1MkWka1gSMExVce8rcFxcWLpUjFhqYiKkjVVubL96tXVqlev9rYd8HkSIAESsDkCrv+62ifqtdVr/Rpscy9f/wGfOiX69hXHj8ueyJ5dSsYwahRPPusPkjVJgARIIHMEqMGZ42bhT8H1aPp0ERgoO/mMMTVoIFatEqVLW/jwaD4JkAAJWAYBarBlvCdDWrlrl8BG8vXrsjZz5RKzZknJgFlIgARIgARMRUCvBWtTGcN+jEzgyRMxYIBo2VIpwEg4GBpKATYyfTZPAiRAAkoCnAcriVjtn7dsEYMHi4cPZQMsXlwsXy6aN7faUXNgJEACJKBiApwHq/jlGMq0a9dEixaiSxeZANvbSxPfM2cowIbCzHZIgARIIKMEOA/OKDGLqq9xPZo4UTx/LrO7YkUp69E771jUYGgsCZAACVgbAWqwtb3RN+PBHBeuR0ePykaYLZsYM0aMHy+cna135BwZCZAACVgGAWqwZbynjFn54oWUcWHmTBETI3uwXj3J9ahs2Yy1xtokQAIkQALGIUANNg5XM7Z64IC00YtzztrF3V1SZSQDRgIGFhIgARIgAXUQoAar4z0YxIqICBEQIG30KvJwIA/SihXCurJWGAQYGyEBEiAB8xKgBpuXv+F6h+vRkCHiwQNZiwUKiCVLRIcOhuuGLZEACZAACRiMAH2TDIbSbA2FhYmOHSXXI20BxpozVqQvXKAAm+29sGMSIAESSI8A58HpEVLz/YQEsWaNlF8hMlJmJpL7YkW6lizloJrHQdtIgARIwDYJUIMt9b2XRN6FOnXEP//IBuDkJEaMkPIx0PXIUl8s7SYBErAhAtRgC3zZsbGFvv12DTIPKs5e1a0ruR6VK2eBQ6LJJEACJGCLBLgfbGlv/eBBUalS0eXLnbQF2M1NLFgg9u+nAFva66S9JEACNk2A82DLef1Pn4rJk6VzztgG1i5wPULehUKFLGcktJQESIAESEAiQA22kO9g+3YxaJC4fVtmrpeXWLRIdO5sIWOgmSRAAiRAAjIC1GDVfxB374phw8QPP8gMtbP7zcOj+blzIndu1Q+ABpIACZAACegmwP1g3VxUcRU7vl9/LeBopBDgUqXOLVw4o3RpCrAqXhONIAESIIHMEqAGZ5acsZ+7fFk0bix69hTh4W+6gusRolGeO/e0alVj98/2SYAESIAEjE2Aa9HGJpzx9mNjxbx5YsoU8eqV7OF335Vcj3x8Mt4inyABEiABElAjAevX4Ng+sRvrbjwq5Gl0VfAurly5EoYwk/JS5dyLaXPvlromU98XWe2X98y77oMn8eH+4i/pgejo6FdjXg0QA1QwDppAAiRAAiQgI3Bnwp3nDs/1gWL9Gmwfal/0UdFqopo+OExZ59juYx6uHkWKFNF0muVlXPsNZ1v93w37hERtM07VLrh+xDuPPV0qa1/NLgqWLlhClDClweyLBEiABEhAHwI7T+/MUi6LPjWtX4MdDjrUu1Cvb92++uAwZZ0/dv/x/vvvd/ZL8iwKCpJcj27elBng6SnmzKnco8cCU5rFvkiABEiABN6OwNIdS53ed9KnDZ7J0oeSMevcvy969BCIs6EtwMh61L27OH9eusVCAiRAAiRgpQSsfx6s2hdnJ0RRRJf8+GPx+LHMyJIlxYoVokkT1VpOw0iABEiABAxCgBpsEIwZb+TKlYkHDlTUzviLNhwdpRXpL74QLi4Zb5FPkAAJkAAJWBgBrkWb/IXFxYmFC5F3QSnAVapIiQhxiwJs8nfCDkmABEjALAQ4DzYt9pMnRb9+4vhxWa/Zs0vJGEaNEg4OprWGvZEACZAACZiTADXYVPSjo8X06SIwUMTHy7ps2VLKelS0qKnsYD8kQAIkQAJqIUANNsmb2LlTDBwobtzQ7uy5s/PFXr2q4vgVCwmQAAmQgE0SoAYb+bUj2vO4cVKMSUXx9//k5cuWTZow7rOSDP9MAiRAAjZDgGeyjPmqt2wRZcsqBbh4cfHbb2Lz5mdZ9IqiYkz72DYJkAAJkIA5CVCDjUP/2jXRvLno0kU8evSmA7geIRPwmTOiWTPj9MpWSYAESIAELImA9a9Fx30Qt7XG1svissFfS3x8/KFDhxKR5VerOMQndv7p/oCvbmV7ITt7dblk9i9Glwjx/lccb6qpfrHZxbgKccfEMYMbxgZJgARIgATMSODesHtR9lH6GGD9Gmz3yM4lxiWXyKUPjgzViYiMOLXvVIMGDZKfKnElctjcs2UuPNVuJyaLw5YPin//v5JxTvbaRtQqW6tCoQouguE4MkSdlUmABEhA7QQcHzs6Juolr3aKaZzaR5Zx+3LkyDF//vy+fftm/NF0nrh586afn98NzWnnFy/E7NlSiCtk/9Uu9epJ+8HYFWYhARIgARKwDQKVKlXauHFjxYoV0x2uXkKdbiu2XgFhnwcMEKGhMg7u7pIqIyIHEjCwkAAJkAAJkEAKAtTgFEgycsEtIUFS39WrhXxXWPj7iyVLRL58GWmMdUmABEiABGyLADU48+87e1DQvrt3la5HBQpI6tuhQ+bb5ZMkQAIkQAK2QYAanKn3HBYmBg/Ou22b7GF7e4FdZ0SjzJEjU43yIRIgARIgAdsiQA3O4PvG4vOaNVJ+hchI2ZMVKkgT4lq1Mtgcq5MACZAACdguAWpwRt792bPSGasjR2TPZM0qAgLE+PHC2TkjbbEuCZAACZCArRNQiwbDRSoyMjIuLi5Xrlx2KjxI/PKlmDVLzJwpYmK0P5mjWbLUOHFClCtn698Rx08CJEACJJBxAmaOVQnn2rFjx5YqVcrFxcXNzS1PnjxZs2YtXbr0uHHjriHco0rKwYOiShUxbZpMgN3cnkyZ0sXTkwKskrdEM0iABEjA4giYcx58/PhxxLiA9LZt29bHxyd37tyYDT958iQ0NHTTpk0rV67cu3dv5cqVzck0IkJMmSKdc8Y2sHZp0wZJfyMTEhLWrTOneeybBEiABEjAkgmYU4OHDx9evXr1oKAghLJSMHz58mWXLl1GjRq1e/dus+Hdvl0MGiRu35YZ4OUlFi8WnTpJF2/eNJtt7JgESIAESMDyCZhTg0+dOoUokikFGFSxIt2vX7/u3bvrQ/jq1aurUibo/e/Jlx1efl/l+wzlbMhx9/l7Q3f7bpXFvUq0Ez+3ybfk40JRLoFifyCaf/XqVcTYiLFirD5Gsg4JkAAJkICNELj/8f0X9i/0Gaw5NbhMmTJ79uzp3bt3ykNYWJTGrXL6nXVycHDASa7URusS5lIwe0F9czYkJlZefbTB6KAsz15pNxhWyGXRSJ8zVfLg6POb089ZRJlaZfRtOTX7eJ0ESIAESMC6CNi/sLcTekUpNmfOhp9++qljx44NGzbs2rWrr6+v5kQ09oNDQkK2bt26a9euLVu2oMJbvpratWtjtl1LH8/dS5ekwJP79sl6dHISI0ZIB7KyZHlLS/g4CZAACZCALRCwjJwNHTp0gNAGBgYOgPJpFUyLGzVqhH3iFi1amOhtIdnRvHnS8atXsumvePddKfKGj4+JzGA3JEACJEACtkTAnGvR4Nw8qURERIQlFSxBe3p6FipUCGekTfcWDh+WIm8EB8t6zJlTTJ8uhgwRDg6ms4Q9kQAJkAAJ2BIBM2uwBrV7UilfvrypyT97JiZN0u16tGyZKFzY1PawPxIgARIgAVsioAoNNg/wHTsk16Nbt2S9588vJf3t0cM8JrFXEiABEiABWyJg5jhZ5kF9756ksm3bygQYATLhCnXuHAXYPC+FvZIACZCA7RGwsXlwYqLYuFE65/z4sexdlywpVq4UjRvb3gfAEZMACZAACZiNgC3Ng69cEU2bip49ZQLs6CiGDROnT1OAzfYNsmMSIAESsFUCNjEPtouPl3Z5p04VSH+kXZCJYfVqUa2arb59jpsESIAESMCcBKxfg/O/elUBc19MgrWLq6v47DO6Hpnz02PfJEACJGDzBKxfg4u9eJFdIcCtWgm4HhUtavNvnwBIgARIgATMScD6NVibbrSr6562bYMrVRLffacPdYQN+eeff5DVWJ/KrAMCSOf44MGD/HDxYtGbwN27dxGaxt7elg5n6A1HZ8VHjx4h10sWho/VSUfXxefPn+PvZk6EHmLRj0BsbCz+SiJio37VlbXwz6DyUip/tn4NbteunbhwIVGIE76+QY0aRWfLJp48SYWG8vKFCxeuXLnCfxyVXFL/M3JJBQcH8x/H1AnpuHP+/Hl8Y87Ob7KB6KjES1oELl++7OHhYdJoehbO/86dO9Dgwow7pPd7fPr0KX7Vq4IzQ5kqffr0KVGihD6PmjNngz72mbfO5s2bkT3i+++/N68ZFtT7jRs36tevf/36dQuy2eymenl5nTx5kosH+r+I9u3b9+rV67333tP/ERuv+cUXX0RFRX3++ec2zkH/4SNx38yZM02QwJ7LX/q/FNYkARIgARIgAUMSoAYbkibbIgESIAESIAH9CVCD9WfFmiRAAiRAAiRgSALUYEPSZFskQAIkQAIkoD8BarD+rFiTBEiABEiABAxJgBpsSJpsiwRIgARIgAT0J0AN1p8Va5IACZAACZCAIQlYf4yOt6GFWBOMnJAhgMDFAB0ZIobKIObk5JTRp2y5Pj4z/sXM0AeAbwyBnzL0iI1XNtk3xhgdaX1piCwDx3ZExUurEu/JCSC+jJubG6noT4DE9GelqRkZGenq6mpnZ5fRB222PgLYJSYmZs2a1WYJZGLgz549M0F0T2pwJl4NHyEBEiABEiABAxDgfrABILIJEiABEiABEsgEAWpwJqDxERIgARIgARIwAAFqsAEgsgkSIAESIAESyAQBanAmoPEREiABEiABEjAAAWqwASCyCRIgARIgARLIBAFqcCag8RESIAESIAESMAABarABILIJEiABEiABEsgEAWpwJqDxERIgARIgARIwAAFqsAEgsgkSIAESIAESyAQBanAmoPEREiABEiABEjAAAWqwASCyCRIgARIgARLIBAFqcKrQfvrppxo1aiD9QIMGDU6cOJFqPZu/MXr06FGjRikwkJ7O7yI+Pj4wMPDdd99FIhBvb++FCxfiSnJNQksJDXHzhw0bVqxYMRcXlypVqmzatEm7DomlJJZ8BSlnGjdu3K1bNxJLgxJu/fLLL8j/oV369u1rsr+V1GDdb+e3337r2LFjqVKlvvzyS/wr6efnd+PGDd1Vbfvq5cuX165dq2BAeql9FNOnT8evLOXLl1+xYkWjRo2GDx/+xRdfaCoTmk5oAwYMWLNmTa9evfD/0qVL/+9//wsKCiIxnawUF1euXLl3717ti/zGdHK7cuVKnjx55moVf39/031jSGjFkpJAkyZNMP2F+uIWfhPPnz9/QEBAymq2fGX//v1169Z1dJRSUI8cOVIbBenp/DCQPw7LKr17906+O3To0OzZs8fFxeEKoaWEFh4ejq9r8eLFmlv4+1imTJkPP/xQ80cSS0ks+crVq1eR3hEFv7UkXyQxncQGDx6Mf+113jIBMc6DdfxiFBERsXv37g8++MDeXuKDZcO2bdv+8MMPOqra8KXcuXO/9957M2fOxA/aGEgvtY/i9u3bSBXcvHnz5Ar16tWLjo6+efMmoemE9vjx49atW2NBVXMXfx89PDxiYmLwRxLTSUxzEavQffr06dChQ6VKlZKrkVhqxDAPLlmyJO7it2HtOqYhRg3W8V7CwsJw1dfXN/mej48PLuIXJR21bfUS+GAbGCVXrlzaDEgvtS+iQIECISEh+H0uucKhQ4ecnZ09PT0JTSc0bAbt2LGjXLlyL1++vHTp0ldffXXs2LGuXbuiMonpJKa5iJ0OfGkLFizgX8w0KCXfggZjT61s2bL4ywgxnj9/Pn6JMdk3Rg3W8Y40f721pQVTvRcvXkRGRuqozUtyAqSX2heRNWtWnMPKli2bpsL69euxyjpo0CAsRxNaatA01yEnWIXGSRkUHNTARRJLjdi1a9fGjBkDGVYsUJGYTmLY4Lh+/fr58+c/+eST7du3N2vWbMSIEbNnzzbZNyZt5rEoCGjmuzgml3xdc0WxUkFuOgmQnk4s2hfv3Lnz6aefYncDZ1bnzJmDW4SWNrTu3bvXrFnz8OHDM2bMwC8xOD1DYjqJaVah27dvj30iRQUS00kMGrx582YcuS9atCgqYO8D5zZwUhK/x5iGGDVYx3vB2iCuPnnyJPkefsYyhWLRVceTvCQE6aX9FWzZsqV///6Yo/z444/YsdNUJrS0oRVMKg0bNsQBScyJ8U8kiekkhsWVU6dOrV69GnuZqIBpA7bP8TM8u0hMJzH8w45fWbRvYbdo3bp1WE4wDTGuRet4L/jbjqsXLlxIvhcaGlqkSBHtmbGOx3gpiQDppfEhYO7bpUsXrKZi7StZgAktNWJw/61evbq2CzXckyAq2B7mZ6YTWnBwMCYM2EfHhAHlyJEj+J0PP8Chi8R0EsMS/Z9//qnZANZU0Pw7nzNnTtMQowbreC/wFYPvJv651KxF4C88vuDOnTvrqMpLKQiQXgokry9APOAFgQOrcHXF3rB2NULTCQ1acvz48b/++iv57oEDB7BmCFcFEtNJbODAgfu0Cg5OwrsGF+BGSGI6ieGsH9ZXdu3alXwXv/kVL148X758JiIGmWFJSeDXX3+FIwQ27bBL365dO3d3d5ydS1mNV0AAJwkV/sGkp/PD2LNnD/6e419J7WgA+Pn58+eoT2gpoWEGXLlyZSwJgtLGjRsRqQMAcTpaU5PEUhJTXKlTp462fzCJpSSGbwwajL2hWbNmff311/A+xzeGfSKTfWPSYRAWnQSwhoNYlViRwJwYsSp11uFFEEipwbhIeim/jVWrVun8Tfzu3buayoSWEhrgQEUwI8GOJtalv//+eywbJlcjsZTEtK8oNJh/MXXiwkonQjAheh3WVxBHFtHEtKsZ+xuzQ2c6/13gRRIgARIgARIgAaMS4H6wUfGycRIgARIgARJIlQA1OFU0vEECJEACJEACRiVADTYqXjZOAiRAAiRAAqkSoAanioY3SIAESIAESMCoBKjBRsXLxkmABEiABEggVQLU4FTR8AYJkAAJkAAJGJUANdioeNk4CZAACZAACaRKgBqcKhreIAESIAESIAGjEqAGGxUvGycBEiABEiCBVAlQg1NFwxskQAIkQAIkYFQC1GCj4mXjJEACJEACJJAqAWpwqmh4gwRIgARIgASMSoAabFS8bJwESIAESIAEUiVADU4VDW+QAAmQAAmQgFEJUIONipeNkwAJkAAJkECqBKjBqaLhDRIgARIgARIwKgFqsFHxsnESIAESIAESSJUANThVNLxBAiRAAiRAAkYlQA02Kl42TgIkQAIkQAKpEqAGp4qGN0iABEiABEjAqASowUbFy8ZJgARIgARIIFUC1OBU0fAGCZAACZAACRiVADXYqHjZOAmQAAmQAAmkSoAanCoa3iABEiABEiABoxKgBhsVLxsnARIgARIggVQJUINTRcMbJGC5BFq0aFG3bl3T2P/jjz9+9913mr6KFSsWGBhomn7ZCwlYAQFqsBW8RA6BBMxJQFuDzWkH+yYBCyRADbbAl0aTSYAESIAErIIANdgqXiMHQQIZIbB+/frq1au7uLhUqFDh22+/TX4UK8nffPMNFpPLly/v5ubWpUuX8PBwzd2YmJhRo0ahQtGiRSdOnLhs2TJfX1/cqlWrFlr4+eef7ezsIiIicCUxMXH69OmlSpVCC507d05uISMGsi4J2AoBR1sZKMdJAiSQRGDhwoXDhw8fMmTI6NGjd+7c2a1bt9jY2I8++kiDZ8WKFXny5IEMX716deTIkR4eHkuXLsWt3r17//LLL5MmTfL09Fy8ePHDhw9dXV1xfcuWLWgqKioKD+bIkQNXFixYULNmTfRy/Pjxzz77zMvLC/U1jfP/JEACCgLUYH4SJGBDBJ4/fz516lSo7+zZszHs999/PyEhAfPanj17YiKLK48ePdq/f7+DgwN+PpZU8ENISAgmu5BbzGvxx/bt2xcpUkSjwYULF4b04llMfDUc3d3df/jhB3t7+9atW1++fPnEiRM2xJdDJYEMEuBadAaBsToJWDKB4OBgrBh37949eRBYcL5z505YWJjmSqtWrTQCjD/mz58/Pj4eP/z999/Ozs4dOnTQ1MmZM2fz5s1TwwDphQBr7ubLl0/TQmqVeZ0EbJwA58E2/gFw+LZF4NatWxhwtWrVNLNe/Iw45W2OAAACPElEQVR5MP7/5MmTggUL4gcsPqckcvPmTVxP1mZUwArz+fPnU9ZMrQWdNXmRBEiAGsxvgARsiAC0E6Pdt29f7ty5tYeNw1aaPyZrs/ZdPIUNYMxok2X4/v37qVHT2UJqlXmdBGycANeibfwD4PBtiwAOPGfPnj00NNT7vwLv3jFjxmTJkiUNEDVq1MC56G3btmnqPHv2bNeuXWnU5y0SIAE9CXAerCcoViMBCyOAqSp8kLSNhicSVqEDAgL69++PY1YVK1Y8fPjw8uXLZ82alfbktWrVqjiH1atXrytXrmBRGo5J+H/yI9j9xTbznj176tWrZ2GMaC4JmJsANdjcb4D9k4BxCOBMMlRTu22oLzQY/kW5cuVavXr1kiVLcLwZrkTDhg1L1wSci8bj8+fPx4Es+CydO3fu5MmTmqdwquvQoUMQ6du3b6fbDiuQAAloE7CDQz2JkAAJkEAaBOD+e+3atbJlyzo5OWmqffjhhy9fvsQ6dhpP8RYJkEC6BLgfnC4iViABWyfw+PFjrGMfOHBAAyIuLg4+xFjKtnUuHD8JvDUBzoPfGiEbIAFrJ4DVsmbNmiFyFuJnYS160aJFf/zxB/aGNaesrX30HB8JGJEANdiIcNk0CVgNAfgmaWJbYhKMTWWIMefBVvNyORAzEqAGmxE+uyYBEiABErBpAtwPtunXz8GTAAmQAAmYkQA12Izw2TUJkAAJkIBNE6AG2/Tr5+BJgARIgATMSIAabEb47JoESIAESMCmCfw/Zw2Tj7YBJGwAAAAASUVORK5CYII=" alt="" />
当向量的大小超过128 Bytes后,就不再需要R去管理了,对于操作系统而言,申请一个大的数据块,还是比较在行的。超过后,操作系统每次申请8 Bytes的倍数的空间。
R对象的内部部件可以与其他对象进行共享,我们看下面的代码:
> x <- :1e6
> object_size(x)
#>4 MB
> y <- list(x, x, x)
> object_size(y)
#>4 MB
>object.size(y)
#>12000192 bytes
>z<-list(rep(x,))
>object_size(z)
#>12 MB
> y1=y[[]]
> y11=y[]
> address(x)
#[] "0x73dee60"
> address(y1)
#[] "0x73dee60"
> address(y11)
#[] "0x1a4e7468"
y的实际大小并不是x的3倍,y并没有将x复制了三次,而是维护一个指针指向x,y1的地址和x的相同,而y11则不是,y[1]访问会重新申请一个新的空间。rep函数会重新复制和神奇你个空间,这也是z空间是y的3倍的原因;另外object.size(y)3倍于object_size函数,原因区别在于上面所说的那样。
如果y的内部数据变化了,情况会怎么样呢?看下面的代码:
> x<-:1e6
> y<-list(x,x,x)
> y[[]][]=
> y1=y[[]]
> y2=y[[]]
> address(x)
#[] "0x1a5156f0"
> address(y2)
#[] "0x1a5156f0"
> address(y1)
#[] "0x6c3dc30"
> object_size(y)
#12 MB
> object_size(y1)
#8 MB
> object_size(x)
#4 MB
更改y第一部分,然后这部分的地址就发生了变化,大小居然变成了2倍;y的剩下的2部分数据,仍然指向原来的x。这就是所谓的“变化时拷贝”的概念,第四部分会重点介绍,那么令热纳闷的是,大小居然变大了一倍,我们看看它们的类型,原来是赋值之后,数值类型由integer变成了numeric:
> class(x)
#[] "integer"
> class(y1)
#[] "numeric"
> class(y[[]])="integer"
这种情况仍然适用于字符串变量,R内部有一个全局的字符串池子,也就是说一个独特的字符串只存储了一份,所以字符串向量占用的空间大小,往往比想象的要小很多,例如:
> object_size("apple")
# B
> object_size(rep("apple",))
# B
2. Memory used & garbage collection
object_size()告诉我们单个对象占用的内存大小,pryr::mem_used()可以给出R所有对象占用的内存大小:
> library(pryr)
> mem_used()
#59 MB
这个数字可能和操作系统报告给我们的不太一致,具体原因如下:
- 该函数返回R对象的空间大小,并不包括R的编译器等部分。
- R和操作系统都是“懒惰”的,直到再次被用到,它们不会回收内存资源。在操作系统没有要求回收内存之前,R要一直占用已有的空间。
- R计数的对象,可能会因为被删除存在间隙,也就是我们常说的“内存碎片”。
mem_change()函数给出一段执行语句下来,内存的变化情况,甚至在什么都不做的情况下,内存都会发生变化,那是因为R会跟踪用户做的操作,所以会保留下来操作的历史。对于内存改变在2KB左右的语句,几乎都可以忽略。
> mem_change(x<-:1e6)
#4 MB
> mem_change(rm(x))
#-4 MB
> mem_change(NULL)
#1.68 kB
在一些语言中,有时候必须显式删除没用的对象去回收内存资源,R提供了一种选择:garbage collection 。可以人为调用gc()函数,其实大部分时候它能够自动运行,如果一个内存对象没有被任何其他对象引用,那么R就会自动回收它。在99%的时候都不需要人工去调用gc()函数,因为R一旦检测到没用的对象就会回收它,除非要人为告诉操作系统要回收内存资源,不过即使调用了也没什么差别,只是在老的windows版本中,没有一种方式将资源交还给操作系统。例如:
> mem_change(x<-:1e6)
#4 MB
> mem_change(y<-x)
#1.62 kB
> mem_change(rm(x))
#1.62 kB
> mem_change(rm(y))
#-4 MB
学习过C/C++或者其他语言的人,可能对“内存泄露”或者“内存漏洞”不会陌生,内存泄露的产生往往是因为一个指向对象的指针始终都没有得到释放。那么在R中,往往存在2种方式可以导致内存泄露:formulas和closures,因为两者保存了上下文的环境信息,而这部分往往是没有用的,而且得不到释放。如下面例子所示,在函数f1内部,1:1e6并没有被返回,当函数执行完毕之后,函数内部变量占用的空间被释放,但是在函数f2和f3内部,返回值都包含了“环境”上下文信息,所以当函数结束之后,函数内部的空间作为返回值返回了,然而确是没有用的。
> f1<-function(){
+ x<-:1e6
+
+ }
> f2<-function(){
+ x<-:1e6
+ a~b
+ }
> f3<-function(){
+ x<-:1e6
+ function()
+ }
> mem_change(x<-f1())
#1.74 kB
> object_size(x)
#48 B
> mem_change(y<-f2())
#4 MB
> object_size(y)
#4 MB
> y
#a ~ b
#<environment: 0x1ab75660>
> mem_change(z<-f3())
#4 MB
> object_size(z)
#4 MB
> z
#function() 10
#<environment: 0x19cfd1a8>
3. Memory profiling with lineprof
mem_change()反映的是运行一块代码,内存变化的情况。有时候,我们想要知道一大块代码中内存一点一点增加的情况,那就需要使用“memory profiling”去抓取每毫秒内存的变化情况。utils::Rprof()
函数能够完成这项工作,但是函数的返回结果不能很好的展示,所以这里使用lineprof包,它提供更好的结果展示。为了展示lineprof::lineprof()是怎么工作的,下面我们拿read.delim()函数为例:
read_delim <- function(file, header = TRUE, sep = ",") {
# Determine number of fields by reading first line
first <- scan(file, what = character(), nlines = ,
sep = sep, quiet = TRUE)
p <- length(first) # Load all fields as character vectors
all <- scan(file, what = as.list(rep("character", p)),
sep = sep, skip = if (header) else , quiet = TRUE) # Convert from strings to appropriate types (never to factors)
all[] <- lapply(all, type.convert, as.is = TRUE) # Set column names
if (header) {
names(all) <- first
} else {
names(all) <- paste0("V", seq_along(all))
} # Convert list into data frame
as.data.frame(all)
}
测试读入的数据来自ggplot2包:
library(ggplot2)
write.csv(diamonds, "diamonds.csv", row.names = FALSE)
使用lineprof时,需要以下几个步骤,首先使用source(),将源代码加载进内存,然后用lineprof()包含调用的语句,最后shine()展示返回的结果。需要注意的是,必须使用source()去加载代码,这是因为lineprof使用srcrefs去匹配代码和运行时间的,而srcrefs是在代码从硬盘加载的时候创建的。shine()函数会打开一个浏览器的网页(RStudio则新生成一个pane)展示lineprof返回的结果,如下图所示,并且阻塞现有的R对话,可以通过 Escape / Ctrl + C 来退出。
library(lineprof) source("readcsv.R")
prof <- lineprof(read_delim("diamonds.csv"))
shine(prof)
aaarticlea/png;base64,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hEUFZYWi17dpupigUPz7O3p6TG2Y76mx34EoIAAElCbQUE9JlDagDhUbzmYNlVy1cijKXnUACk2AABAAAkAACDQ+gaBD++G5V+NjB41AAAgAASCgHgKwiqcejiAFCAABIAAEGpMAZK/GpA26gAAQAAJAQD0EIHuphyNIAQJAAAgAgcYkIMpexJsnjakSdAEBIAAEmoSAJo51DWezpkuGuVeTXESgFAgAASAABOpFALJXvfBBYyAABIAAEGgSApC9mgQ7KAUCQAAIAIF6EYDsVS980BgIAAEgAASahABkrybBDkqBABAAAkCgXgQge9ULHzQGAkAACACBJiEA2atJsINSIAAEgAAQqBcByF71wgeNgQAQAAJAoEkIQPZqEuygFAgAASAABOpFALJXvfBBYyAABIAAEGgSApC9mgQ7KAUCQAAIAIF6EYDsVS980BgIAAEgAASahABkrybBDkqBABAAAkCgXgQge9ULHzQGAkAACACBJiEA2atJsINSIAAEgAAQqBcByF71wgeNgQAQAAJAoEkIQPZqEuygFAgAASAABOpFALJXvfBBYyAABIAAEGgSApC9mgQ7KAUCQAAIAIF6EUCFQmG9BEBjIAAEgAAQAAKNRSDo0P5ZX87n83gw92os5KAHCAABIAAE1EcAspf6WIIkIAAEgAAQaCwCkL0aizToAQJAAAgAAfURgOylPpYgCQgAASAABBqLgCh7PX78uLHUgR4gAASAQJMR0MSxruFs1nTJMPdqsgsJFAMBIAAEgECdCUD2qjM6aAgEgAAQAAJNRgCyV5OhB8VAAAgAASBQZwKQveqMDhoCASAABIBAkxFoQdmL9+7IWNcxgYm8JoMJioEAEAACQKCRCNQtexU/+s5r1qVMHCl+vHb4rIvEB5kDz436beVED2cn4ugzbMrK4y+KZatU/y3Mve0/bffLcuoacAYIAAEgAASAgDQBel1w8DJjEuidJutj/IyYeFbXya1kcqAw798flga8HPjtr+s/0yvNeBOTZGbColREZLprT/NsKM/DCSAABIAAEAACMgTqMvcSliRGZZn3sGYhxYlRXGvH1kwZobyPcW/K2k2a59PLvlNXh/7eM6a5mdKIOsKil8FrJnsQ8zG3UV/te8gVIAiefXvN1JVheaknfd2cXHz/SCHKpA+86OW5DdO/cCXa9B3pdypBPEETFr++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" alt="" />
图中四列列出了每一行代码的性能:
- t,每一行代码运行的时间花费,单位为s,具体见measuring performance。
- a,每一行代码运行过程中分配的内存的大小。
- r,每一行代码释放的内存的大小。分配的是确定的,释放空间则是随机的,这个依赖于gc()函数,也就是说函数只告诉你空间不再使用了。
- d,向量的复制发生的次数。R向量的复制发生在向量发生了变化的时候。
你可以在每一个颜色段上停留,网页会给出详细的运行参数,也可以在R会话中输出返回的结果:
> prof
Reducing depth to (from )
Common path: readcsv.R
time alloc release dups ref src
0.042 1.939 0.271 readcsv.R# read_delim/scan
0.018 0.786 0.562 readcsv.R# read_delim/lapply
0.002 0.416 0.000 readcsv.R# read_delim/as.data.frame
- scan()函数,分配的空间大小为1.9M,而硬盘上的文件大小为2.8M,那么缺少的部分在哪里呢?首先,R不需要存储csv文件中的逗号,再者就是R存在全局的字符串线程池,相同的字符串在内存中只分配一次空间。
- lapply()函数,分配了0.7M的空间,同时释放了0.5M的空间,那是因为字符串转化为numeric或者integer空间会变小。
- as.data.frame(),复制的次数是最多的,而且花费了大约0.4M的内存空间,那是因为as.data.frame函数是个比较糟糕的函数,先看看由list转化为data.frame函数的相关代码:
x <- eval(as.call(c(expression(data.frame), x, check.names = !optional,
stringsAsFactors = stringsAsFactors)))这个部分x被复制了很多次,具体关于复制的问题,我们下面讨论。
这种方法,存在一些弊端,例如:
- read.delim()函数总共运行0.062s,即使是每毫秒收集一次数据,仅仅有62个样本。
- 另外GC函数是懒惰的,我们始终都不知道哪些是不需要的内存。不过可以人为强制在每行代码运行后,执行gc函数,只要在lineprof函数中加入torture=T,不过会导致运行时间非常慢,正如参数的含义一样“折磨=True”,下面是执行的结果:
> prof<-lineprof(read.delim("diamonds.csv"),torture=T)
> prof
Reducing depth to 2 (from 10)
time alloc release dups ref
1 0.001 0.001 0.000 0 character(0)
2 0.009 0.001 0.004 0 "lazyLoadDBfetch"
3 0.001 0.000 0.000 1 c("lazyLoadDBfetch", "..getNamespace")
4 0.004 0.003 0.000 0 "lazyLoadDBfetch"
5 0.002 0.007 0.000 0 "read.delim"
6 0.291 0.105 0.004 1 c("read.delim", "lazyLoadDBfetch")
7 0.001 0.001 0.000 0 "read.delim"
8 19.703 3.900 0.375 175 c("read.delim", "read.table")
9 0.002 0.000 0.000 0 character(0)
src
1
2 lazyLoadDBfetch
3 lazyLoadDBfetch/..getNamespace
4 lazyLoadDBfetch
5 read.delim
6 read.delim/lazyLoadDBfetch
7 read.delim
8 read.delim/read.table
9
4. Modification in place
下面代码中的x会发生什么?
> x<-:
> address(x)
#[1] "0x4533b50"
> x[]<-as.integer()
有两种情况:
- R会在x[4]原来的地方,将值更改为5;
- R将x复制一份,在新的地址上进行更改,然后将x的指针指向新开辟的空间地址。
实际上R到底会使用哪一种方式,依赖于上下文的环境。上面的代码R会在原先的地址上对数据进行更改。但是,当有另外一个变量指向了x的地址空间,那么x会重新生成一个新的copy。我们看下面的例子:
library(pryr)
x <- :
c(address(x), refs(x))
# [1] "0x10310006" "1" y <- x
c(address(y), refs(y))
# [1] "0x103100060" "2"
如果使用的是RStudio,refs始终都是2,那是因为环境浏览器也会指向各个对象。refs()函数只是一个判断,它仅仅可以区分1和多于1的引用数量,也就是说下面的例子refs始终会返回2。
> x<-:
> y<-x
> rm(y)
#本应该会变成1,因为我们删除了y
> refs(x)
#[1] 2 > x<-:
> y<-x
> z<-x
#本应该会变成3
> refs(x)
#[1] 2
只要refs函数返回的值为1时,x会在原始的地方发生变化,而返回值为2时,就会发生copy,我们看下面例子,x的引用次数本来在删除y之后会变为1,但是refs返回2,而且更改x的值,x会发生拷贝,这个有待研究。
> x<-:
> y<-x
> refs(x)
#[1]
> rm(y)
> refs(x)
#[1]
> address(x)
#[1] "0x69d7560"
> x[]<-as.integer()
> address(x)
#[1] "0x69d7758"
函数tracemem会在监视变量地址发生变化时,输出变化前后不同的地址,当监视的变量被重新赋值时,则取消监视。下面的代码为什么x[2]<-10之后为什么会发生2次的地址变迁?第一次是由于refs返回值为2,更改x的值需要重新生成一份copy;第二次地址变迁,是由于x的类型发生变化,由integer变成了numeric,这也是上面的代码中一直加上as.integer的原因。
> x<-:
> y<-x
> tracemem(x)
#[1] "<0x6a53768>"
> x[]<-
#tracemem[0x6a53768 -> 0x6a53888]:
#tracemem[0x6a53888 -> 0x6303e80]:
非R的原函数访问R的对象,都会使得该对象的引用次数增加,而原函数则不会。一般而言,如果一个R对象的被引用次数为1,那么R的原函数都不会发生拷贝,在原先的地址空间对数据进行更改。这样的原函数一般包括[[<-
, [<-
, @<-
, $<-
, attr<-
, attributes<-
, class<-
, dim<-
, dimnames<-
, names<-
, and levels<-
。如果想需求其他的方式防止拷贝的次数过多,那么RCpp包是个不错的选择。
> f<-function(x) return(x[])
> {x<-:;f(x);refs(x)}
#[1]
> {x<-:;sum(x);refs(x)}
#[1] 1
5. Loops
R的循环那是出了名的慢啊,究竟是为什么,我们看下面的代码,每次循环过程中x的地址都在发生变化:
> x<-:
> tracemem(x)
[1] "<0x622bc90>"
> for(i in :)
+ x[i]<-x[i]-median(x)
#tracemem[0x622bc90 -> 0x60fd910]: sort.int sort.default sort mean median.default median #median内部的原因引起refs值变为2,同时引起了复制。
#tracemem[0x622bc90 -> 0x60fde20]: #x类型变换引起复制
#tracemem[0x60fde20 -> 0x53d2610]: #[<-和refs值为2,引起复制
#tracemem[0x53d2610 -> 0x66fa270]: sort.int sort.default sort mean median.default median
#tracemem[0x53d2610 -> 0x6692f40]:
#tracemem[0x6692f40 -> 0x5277820]: sort.int sort.default sort mean median.default median
#tracemem[0x6692f40 -> 0x5bb7b70]:
#tracemem[0x5bb7b70 -> 0x68506f0]: sort.int sort.default sort mean median.default median
#tracemem[0x5bb7b70 -> 0x46ec9d0]:
#tracemem[0x46ec9d0 -> 0x3e54170]: sort.int sort.default sort mean median.default median
#tracemem[0x46ec9d0 -> 0x2ce85a0]:
下面的代码一个简单的赋值操作,x的地址却变化了三次,那是因为[<-.data.frame并不是R的原函数:
> x <- data.frame(matrix(runif( * 1e4), ncol = ))
> medians <- vapply(x, median, numeric())
> tracemem(x)
[1] "<0x6692f40>"
> for(i in :){ x[,i]<-x[,i]-median(i) }
tracemem[0x6692f40 -> 0x46ec9d0]:
tracemem[0x46ec9d0 -> 0x3e54170]: [<-.data.frame [<-
tracemem[0x3e54170 -> 0x66f9ec0]: [<-.data.frame [<-
tracemem[0x66f9ec0 -> 0x66fa270]:
tracemem[0x66fa270 -> 0x3943410]: [<-.data.frame [<-
tracemem[0x3943410 -> 0x3c1d620]: [<-.data.frame [<-
tracemem[0x3c1d620 -> 0x3f39a50]:
tracemem[0x3f39a50 -> 0x6c08650]: [<-.data.frame [<-
tracemem[0x6c08650 -> 0x4b22f50]: [<-.data.frame [<-
tracemem[0x4b22f50 -> 0x44d5120]:
tracemem[0x44d5120 -> 0x3a63420]: [<-.data.frame [<-
tracemem[0x3a63420 -> 0x2ee6d40]: [<-.data.frame [<-
tracemem[0x2ee6d40 -> 0x3be2650]:
tracemem[0x3be2650 -> 0x506ae30]: [<-.data.frame [<-
tracemem[0x506ae30 -> 0x2dea9c0]: [<-.data.frame [<-
那么将data.frame换成list则不会出现上面的问题:
> y<-as.list(x)
tracemem[0x2dea9c0 -> 0x45b28b0]: as.list.data.frame as.list
> tracemem(y)
[] "<0x45b28b0>"
> for(i in :)
+ y[[i]]<-y[[i]]-median(i)
tracemem[0x45b28b0 -> 0x5018fa0]:
发生复制很多的地方,建议使用RCpp.
R之内存管理的更多相关文章
- 【R笔记】R的内存管理和垃圾清理
笔记: 1.R输入命令时速度不要太快,终究是个统计软件,不是编程! 2.memory.limit()查看当前操作系统分配内存给R的最大限度(单位是M?) 3.要经常 rm(object) 或者 rm( ...
- R语言内存管理
http://www.cnblogs.com/cloudtj/articles/5478281.html
- R语言之内存管理
转载于:http://blog.csdn.net/hubifeng/article/details/41113789 在处理大型数据过程中,R语言的内存管理就显得十分重要,以下介绍几种常用的处理方法. ...
- R内存管理与垃圾清理
1.内存查看 memory.limit():查看内存大小 memory.limit(n):申请内存大小 memory.size(NA):查看内存大小 memory.size(T):查看已分配的内存 m ...
- Swift中的可选链与内存管理(干货系列)
干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...
- Android 内存管理 &Memory Leak & OOM 分析
转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...
- Linux0.11内核--内存管理之2.配合fork
[版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5598451.html ] 在上一篇的fork函数中,首先一上来就调用get_free_page ...
- Linux0.11内核--内存管理之1.初始化
[版权所有,转载请注明出处.出处:http://www.cnblogs.com/joey-hua/p/5597705.html ] Linux内核因为使用了内存分页机制,所以相对来说好理解些.因为内存 ...
- 内存管理内幕mallco及free函数实现
原文:https://www.ibm.com/developerworks/cn/linux/l-memory/ 为什么必须管理内存 内存管理是计算机编程最为基本的领域之一.在很多脚本语言中,您不必担 ...
随机推荐
- 写了一个简单的CGI Server
之前看过一些开源程序的源码,也略微知道些Apache的CGI处理程序架构,于是用了一周时间,用C写了一个简单的CGI Server,代码算上头文件,一共1200行左右,难度中等偏上,小伙伴可以仔细看看 ...
- Effective C++ —— 实现(五)
条款26 : 尽可能延后变量定义式的出现时间 1. 你不只应该延后变量的定义,直到非得使用该变量的前一刻为止,甚至应该尝试延后这份定义直到能够给它初值实参为止.这样,不仅能够避免构造(和析构)非必要对 ...
- 计算时间:一个C++运算符重载示例
Time类是一个用于计算时间的类,其原型如下:程序清单11.1 mytime0.h // mytime0.h -- Time class before operator overloading #if ...
- AVL 平衡树
AVL是一种平衡二叉树,它通过对二叉搜索树中的节点进行旋转使得二叉搜索树达到平衡.AVL在所有的平衡二叉搜索树中具有最高的平衡性. 定义 平衡二叉树或者为空树或者为满足如下性质的二叉搜索树: 左右子树 ...
- java基础---->多线程之Daemon(五)
在java线程中有两种线程,一种是用户线程,另一种是守护线程.守护线程是一种特殊的线程,当进程中不存在非守护线程了,则守护线程自动销毁.今天我们通过实例来学习一下java中关于守护线程的知识.我是个平 ...
- UVa 673 Parentheses Balance (stack)
题目描述 : 判断字符串是不是符合正确的表达式形式. 要点 : 考虑字符串为空的时候,用getline输入,每一次判断后如果为No则要清空栈.对称思想. 注意输入格式. 代码: #include &l ...
- ios 图片拉伸不变形的方法
如果一个椭圆图片,原图大小为30*30,而我们让它显示100*30,那么这个图片就会被拉伸,而且效果很难看.用下边的方法可以创建一个局部不被拉伸的图片. UIImage * buttonBg = [[ ...
- java合并两个升序数组为一个新的有序数组
转自:http://blog.csdn.net/laozhaokun/article/details/37531247 题目:有两个有序数组a,b,现需要将其合并成一个新的有序数组. 简单的思路就是先 ...
- rest_framework之序列化详解 06
拿到所有的角色数据 1.urls.py 2.models.py 假设只有3个角色 3.views.py from api import models import json json只能序列化pyt ...
- kibana 和ES安装配置常见问题解决
1.下载相同版本的kibana和ES: es5.6.5下载地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5 ...