异或链表
我最近发现了下面的链接,我发现它非常有趣。
http://en.wikipedia.org/wiki/XOR_linked_list
- 通用调试工具 无法遵循 XOR 链,使得 调试比较困难; [1]
- 内存减少的代价 使用量是代码的增加 复杂性,使维护工作更加繁琐 昂贵的;
- 大多数垃圾收集方案都会这样做 不适用于这样做的数据结构 不包含文字指针;
- 指针的 XOR 未定义在 一些上下文(例如,C 语言), 尽管许多语言都提供了一些 之间的类型转换 指针和整数;
- 如果出现以下情况,指针将不可读 一个人没有遍历该列表 - 因为 例如,如果指向列表的指针 项目包含在另一个数据中 结构;
- 在遍历列表时,您需要 记住地址 之前访问过的节点 计算下一个节点的地址。
现在我想知道这是否是低级语言独有的,或者在 C# 中是否也可能?
是否有任何类似的选项可以使用 C# 产生相同的结果?
I recently came across the link below which I have found quite interesting.
http://en.wikipedia.org/wiki/XOR_linked_list
- General-purpose debugging tools
cannot follow the XOR chain, making
debugging more difficult; [1] - The price for the decrease in memory
usage is an increase in code
complexity, making maintenance more
expensive; - Most garbage collection schemes do
not work with data structures that do
not contain literal pointers; - XOR of pointers is not defined in
some contexts (e.g., the C language),
although many languages provide some
kind of type conversion between
pointers and integers; - The pointers will be unreadable if
one isn't traversing the list — for
example, if the pointer to a list
item was contained in another data
structure; - While traversing the list you need to
remember the address of the
previously accessed node in order to
calculate the next node's address.
Now I am wondering if that is exclusive to low level languages or if that is also possible within C#?
Are there any similar options to produce the same results with C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
TL;DR 我快速编写了一个概念验证XorLinkedList 实现 在 C# 中。
使用 C# 中的不安全代码绝对可以做到这一点。但有一些限制:
where T : struct
)后者似乎是因为您无法将泛型参数限制为非托管结构。仅使用
where T : struct
您还可以允许包含托管引用的结构。这意味着您的 XorLinkedList 只能保存原始值,如整数、指针或其他非托管结构。
我知道, C# 中的低级编程
非常脆弱。 C# 指针和 IntPtr 不支持 XOR 运算符(可能是个好主意)。
之后不要忘记
Marshal.FreeHGlobal
这些节点(实现完整的 IDisposable 模式,并确保将免费调用放在if(dispose)
块之外。结论 就
我个人而言,我永远不会在 C# 中使用 XorLinkedList(也许)。当我在 C 中编写非常低级的系统内容(例如内存分配器或内核数据结构)时,在任何其他设置中,存储效率的微小提高确实不值得,因为您不能将其与托管对象一起使用。在 C# 中,它对于日常编程来说几乎没有用处。
而且,即使是主内存,存储也几乎是免费的,如果您使用 C#,您可能不太关心存储,我在某处读到过 CLR 对象头。 40字节,所以这个指针将是你最不担心的;)
TL;DR I quickly wrote a proof-of-concept XorLinkedList implementation in C#.
This is absolutely possible using unsafe code in C#. There are a few restrictions, though:
where T : struct
)The latter seems to be because you cannot restrict the generic parameter to unmanaged structs. With just
where T : struct
you'd also allow structs that contain managed references.This means that your XorLinkedList can only hold primitive values like ints, pointers or other unmanaged structs.
Low-level programming in C#
Very fragile, I know. C# pointers and IntPtr do not support the XOR-operator (probably a good idea).
Don't forget to
Marshal.FreeHGlobal
those nodes afterwards (Implement the full IDisposable pattern and be sure to place the free calls outside theif(disposing)
block.Conclusion
Personally, I would never use an XorLinkedList in C# (maybe in C when I'm writing really low level system stuff like memory allocators or kernel data structures. In any other setting the small gain in storage efficiency is really not worth the pain. The fact that you can't use it together with managed objects in C# renders it pretty much useless for everyday programming.
Also storage is almost free today, even main memory and if you're using C# you likely don't care about storage much. I've read somewhere that CLR object headers were around ~40 bytes, so this one pointer will be the least of your concerns ;)
C# 通常不允许您在该级别操作引用,因此不幸的是。
C# doesn't generally let you manipulate references at that level, so no, unfortunately.
作为已提出的不安全解决方案的替代方案。
如果您使用数组或列表集合支持链接列表,其中“下一个”和“上一个”而不是内存指针指示数组中的索引,您可以实现此异或,而无需诉诸使用不安全的功能。
As an alternative to the unsafe solutions that have been proposed.
If you backed your linked list with an array or list collection where instead of a memory pointer 'next' and 'previous' indicate indexes into the array you could implement this xor without resorting to using unsafe features.
有多种方法可以在 C# 中使用指针,但只能暂时拥有指向对象的指针,因此在这种情况下不能使用它们。造成这种情况的主要原因是垃圾收集——只要您可以执行异或指针之类的操作并稍后对其进行反异或,GC 就无法知道收集某些对象是否安全。
您可以通过使用一个大数组中的索引来模拟指针来制作非常类似的东西,但是您必须自己实现一种简单形式的内存管理(即,当创建新节点时,我应该将其放在数组中的哪个位置?)。
另一种选择是使用 C++/CLI,它一方面允许您充分灵活地使用指针,另一方面允许您在需要时使用 GC 和访问框架。
There are ways to work with pointers in C#, but you can have a pointer to an object only temporarily, so you can't use them in this scenario. The main reason for this is garbage collection – as long as you can do things like XOR pointers and unXOR them later, the GC has no way of knowing whether it's safe to collect certain object or not.
You could make something very similar by emulating pointers using indexes in one big array, but you would have to implement a simple form of memory management yourself (i.e. when creating new node, where in the array should I put it?).
Another option would be to go with C++/CLI which allows you both the full flexibility of pointers on one hand and GC and access to the framework when you need it on the other.
当然。您只需要编写该类的代码即可。 C# 中的异或运算符是 ^
这应该就是开始编码所需的全部内容。
请注意,这将要求代码被声明为“不安全”。请参阅此处:了解如何在c#.
Sure. You would just need to code the class. the XOR operator in c# is ^
That should be all you need to start the coding.
Note this will require the code to be declared "unsafe." See here: for how to use pointers in c#.
在这里进行广泛的概括:C# 似乎已经走上了可读性和干净接口的道路,而不是位摆弄和尽可能密集地打包所有信息的道路。
因此,除非您有特殊需要,否则您应该使用为您提供的列表。未来的维护程序员会为此感谢你。
Making a broad generalization here: C# appears to have gone the path of readability and clean interfaces and not the path of bit fiddling and packing all the information as dense as possible.
So, unless you have a specific need here, you should use the List you are provided. Future maintenance programmers will thank you for it.
这是可能的,但是您必须了解 C# 如何看待对象。实例变量实际上并不包含对象,而是指向内存中对象的指针。
dt 是指向内存中包含 DateTime 方案的结构的指针。
因此,您可以执行这种类型的链表,尽管我不确定为什么您会这样做,因为框架通常已经实现了最有效的集合。作为一个思想实验,这是可能的。
It is possible however you have to understand how C# looks at objects. An instance variable does not actually contain an object but a pointer to the object in memory.
dt is a pointer to a struct in memory containing the DateTime scheme.
So you could do this type of linked list although I am not sure why you would as the framework typically has already implemented the most efficient collections. As a thought expirament it is possible.