在阅读有关C数据结构的书时,我遇到了"内存高效的双重链接列表"这个术语.它只有一行说一个内存有效的双向链表使用比普通双链表更少的内存,但做同样的工作.没有更多的解释,也没有给出任何例子.只是有人认为这是从一本期刊中获取的,而在"Brackets"中则是"Sinha".
在Google上搜索后,我最接近的就是这个.但是,我什么都听不懂.
有人能解释一下C中的内存高效双链表是什么?它与正常的双向链接列表有什么不同?
编辑:好的,我犯了一个严重的错误.看到我上面发布的链接,是文章的第二页.我没有看到有第一页,并认为给出的链接是第一页.文章的第一页实际上给出了解释,但我不认为它是完美的.它只讨论了Memory-Efficient Linked List或XOR Linked List的基本概念.
c memory-efficient xor-linkedlist data-structures mem.-efficient-linkedlist
说有一个向量x:
x <- c("a", " ", "b")
Run Code Online (Sandbox Code Playgroud)
我想快速把它变成单个字符串"a b".有没有办法在没有循环的情况下做到这一点?我知道循环我能做到这一点:
y <- ""
for (i in 1:3){
paste(y, x[i], sep = "")
}
> y
[1] "a b"
Run Code Online (Sandbox Code Playgroud)
但是我需要在很多次迭代中做到这一点,并且必须循环遍历这个并且每次用新的替换原始将变得非常耗时.我总是希望能够做到这样的事情:
x <- paste(x)
Run Code Online (Sandbox Code Playgroud)
好像paste()可以巧妙地划分向量本身的元素,但我知道它不能.有没有其他功能,或更有创意的方式来使用paste(),这可以有效地实现这一目标?
A 是一个整数数组.
所有的值之间0,以A.Length-1
它的意思是 0 <= A[i] <= A.Length-1
我应该找到重复的元素; 如果有多个重复元素,则选择重复项目索引较低的元素.
例如:
a = [3, 4, 2, 5, 2, 3]
Run Code Online (Sandbox Code Playgroud)
然后
result = 2
Run Code Online (Sandbox Code Playgroud)
这是一个面试问题.我使用另一个数组来存储项目并检查它何时重复.然后它给了我一些测试用例的超时时间.采访者建议只在数组上循环一次,不要创建任何额外的数据结构.
我正在寻找最节省内存的方法来计算复杂numpy ndarray的绝对平方值
arr = np.empty((250000, 150), dtype='complex128') # common size
Run Code Online (Sandbox Code Playgroud)
我还没有找到一个完全可以做到的ufunc np.abs()**2.
由于该大小和类型的数组占用大约半GB,我正在寻找一种主要的内存效率方式.
我也希望它是可移植的,所以理想情况下是ufuncs的一些组合.
到目前为止,我的理解是,这应该是最好的
result = np.abs(arr)
result **= 2
Run Code Online (Sandbox Code Playgroud)
它将不必要地计算(**0.5)**2,但应该**2就地计算.总的来说,峰值内存要求只是原始数组大小+结果数组大小,应该是1.5*原始数组大小,因为结果是真实的.
如果我想摆脱无用的**2电话,我必须做这样的事情
result = arr.real**2
result += arr.imag**2
Run Code Online (Sandbox Code Playgroud)
但如果我没有记错,这意味着我将不得不为分配内存都实部和虚部的计算,因此峰值内存使用量是2.0*原始数组的大小.这些arr.real属性还返回一个非连续的数组(但这个问题不太重要).
有什么我想念的吗?有没有更好的方法来做到这一点?
编辑1:我很抱歉没有说清楚,我不想覆盖arr,所以我不能用它作为出来.
通过小字节数组我的意思是从10长度最多为30个字节的阵列.
通过商店我的意思是将它们存储在RAM中,而不是序列化并持久保存到文件系统.
系统macOS 10.12.6,Oracle jdk1.8.0_141 64位,JVM args -Xmx1g
示例:
预期的行为new byte[200 * 1024 * 1024]是≈200mb的堆空间
public static final int TARGET_SIZE = 200 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
byte[] arr = new byte[TARGET_SIZE];
System.gc();
System.out.println("Array size: " + arr.length);
System.out.println("HeapSize: " + Runtime.getRuntime().totalMemory());
Thread.sleep(60000);
}
Run Code Online (Sandbox Code Playgroud)
public static final int TARGET_SIZE = 200 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
final …Run Code Online (Sandbox Code Playgroud) 我有一个包含数组的非常大的JSON文件.是否可以使用jq将此数组拆分为几个固定大小的较小数组?假设我的输入是这样的:[1,2,3,4,5,6,7,8,9,10]我想把它分成3个元素的长块.所需的输出jq将是:
[1,2,3]
[4,5,6]
[7,8,9]
[10]
Run Code Online (Sandbox Code Playgroud)
实际上,我的输入数组有近300万个元素,都是UUID.
"新"有多贵?我的意思是,如果我的目标是重复使用同一个对象,或者如果对象是"超出范围",那么它与清空它是一样的吗?
例如,假设一个方法创建一个列表:
List<Integer> list = new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)
在方法结束时,列表不再使用 - 它是否意味着没有分配给它的内存,或者它是否意味着有一个指向它的空指针(因为它是'创建').
或者,我可以向方法发送一个'list'并在方法结束时将其清空:list.removeAll(list);将从内存的角度来看有什么不同吗?
谢谢!
我的一个朋友向我展示了以下Python代码:
a[1:] == a[:-1]
Run Code Online (Sandbox Code Playgroud)
如果所有项目a都相同,则返回True .
我认为代码很难从一见钟情中理解,而且 - 它在内存使用方面效率低下,因为a将为比较创建两个副本.
我用Python dis来看看幕后发生了什么a[1:]==a[:-1]:
>>> def stanga_compare(a):
... return a[1:]==a[:-1]
...
>>> a=range(10)
>>> stanga_compare(a)
False
>>> a=[0 for i in range(10)]
>>> stanga_compare(a)
True
>>> dis.dis(stanga_compare)
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 SLICE+1
7 LOAD_FAST 0 (a)
10 LOAD_CONST 2 (-1)
13 SLICE+2
14 COMPARE_OP 2 (==)
17 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
归结为两个切片命令 - SLICE+1和SLICE+2.文档不清楚这些操作码是否实际创建了一个新副本a,或仅仅是对它的引用.
a …这可能是之前被问过的,但我找不到任何这样的帖子.是否有类使用ASCII字符串?好处很多:
Jon Skeet编写了一个基本的AsciiString实现并证明了#2,但我想知道是否有人进一步采用了这个并完成了这样的课程.我确信会有用途,虽然没有人会采用这样的路线,因为所有现有的String函数都必须手动重新实现.String <> AsciiString之间的转换将分散在各处,使一个简单的程序复杂化.
有这样的课吗?哪里?
在常规的面向对象实践中,并不是罕见的对象具有多个不相关的成员属性.当物体被处理时,在不同的通道中进行处理并不罕见,这些通道针对其属性的不同部分.
在这方面,创建对象集合的典型方法似乎不是非常有效的方法.考虑到计算机访问内存的方式和缓存行的平均大小,很有可能缓存内存正在填充不需要的内容,但恰好是相邻的,因此最终浪费缓存容量并增加停顿和执行的延迟.
更糟糕的是使用多态和动态分配对象的做法,没有内存池和自定义分配器.在这种情况下,不仅缓存会被不需要的数据填充,而且由于动态内存分配使用的任意地址,预取程序也无法正常工作.
拯救是回到OOP之前的时间并选择数据导向,这似乎是开发性能关键应用程序,操作系统等的首选.但为什么不使用两者的混合版本呢?排序的数据面向对象的编程?
在那么久的提议之后,让我们来看看手头的问题.我没有足够大的项目来测试这个概念的效率,所以社区的理论专业知识非常受欢迎.
如果不是存储自己的数据成员的对象,它们只存储对集合的引用,其数据成员按顺序存储在它们自己的容器中,并且它们的成员方法从这些容器返回数据,这样就不需要数据结束的几率应该减少在前往CPU的路上,并且增加近期"未来"所需的数据几率.逻辑假设是这种方法将提高预取器效率,缓存命中率和使用效率,并且还将减少自动和手动并行化中涉及的延迟.
你怎么看?
后期编辑:如果我们考虑结构和类填充,应用"数据方向模式"可能会更有利,如果"模型"有一个char和一个int数据成员,以OOP方式它将被填充,这只会污染进一步缓存,但是面向数据的存储模式可以顺序存储所有chars和所有ints,没有空间和缓存浪费.
oop performance caching memory-efficient data-oriented-design