2

我的团队正在使用 Ruby 开发 MMO 服务器,我们选择开始将计算密集型操作转移到 C 扩展中。作为这项工作的一部分,我们将实际的数据存储移到了 C 中(使用 Data_Get_Struct 等)。因此,例如,每个 Ruby“Zone”对象都有一个关联的“ZoneKernel::Zone”C 结构,其中存储了实际的二进制数据。

基本上,我想知道这是否是一个糟糕的主意。我对 ruby​​ 内部结构不是很熟悉,但只要父 Zone 保留在 ruby​​ 端的内存中(从而防止对 C 数据进行垃圾收集),数据似乎就应该没问题。

一个警告是,我们已经收到了导致服务器崩溃的半常规“堆栈一致性错误”——这似乎是一个相关的内存问题(而不仅仅是你的花园品种段错误)——如果有人知道那可能是什么,我也将不胜感激!

4

2 回答 2

1

文档中所述Data_Wrap_Struct(klass, mark, free, ptr)功能

free参数是释放指针分配的函数。如果是-1,指针将被释放。

这些mark/free函数在 GC 执行期间被调用。

当对应的 Ruby 对象完成时,你的包装原生结构将被自动释放。在此之前,除非您手动释放,否则您的数据不会被释放。

编写 C 扩展并不能保证性能提升,但它几乎总是会增加代码的复杂性。分析您的服务器以衡量您的性能提升,并Zone在可行的情况下用纯 Ruby 开发您的类。

于 2012-02-09T19:39:58.477 回答
0

一般来说,我喜欢保留任何可能在我的来源之外发生变化的数据。从 YAML 或数据库加载它意味着您可以根据自己的喜好调整数据,而无需重新编译。显然,如果您的编译时间和加载时间很快,那么这不是什么大问题,但将两者分开仍然是个好主意。

我喜欢 YAML,因为它是一种标准格式,因此您可以从任意数量的语言访问同一个文件。您可以将其直接加载到 C 端或 Ruby 端,具体取决于看起来更快/更智能的方式。

于 2012-02-09T19:36:10.817 回答