繁体   English   中英

如何在golang中正确使用judy array lib?

[英]How to use judy array lib properly in golang?

在golang中,调用C库的方式与在其他大型机动态语言(如PHP / Python / Java)中使用的方式不同,因为Golang具有不同的多任务机制,该机制不是基于OS线程的,因此调用c函数可能会导致上下文切换或线程据我了解切换。 在我的项目中,我尝试使用Golang中的Judy Array(作为队列工作人员)来进行一些简单但与dict相关的大量计算,例如“选择不同”,因此

涉及这种c lib(用于相对较高的密度计算)并尽可能减少引入的性能开销的最佳实践是什么?

尽管有标题,但这里的问题实际上包括两部分:关于golang和C接口以提高效率的通用部分,以及关于对judy数组的高性能使用的特定部分。

该线程似乎总结了成本: https : //groups.google.com/forum/#!topic /golang-nuts/ RTtMsgZi88Q ,所以是的,与直接C相比,它很昂贵,因此您应该尽量减少Go的交叉点到C。

这是另外有关judy数组的建议:我以前在C / C ++代码中使用过judy数组。 在某些地方,图书馆的界面不直观。 并且默认情况下,它使用基于C宏的API,这使正确使用接口变得很棘手,因为编译器无法像往常一样提供太多帮助。

因此,我建议您首先使用C编写测试和基准,以便您了解API及其奇怪的情况。 当为我的应用程序(相对于字符串的C ++矢量)进行基准测试时,Judy数组的速度提高了3倍,因此值得这么做。 但是将任务分为三个阶段。 首先,执行您想在C中执行的操作,并确保它可以在您自己的C代码中按预期工作。 然后扩展基本的C接口以处理您需要完成的工作,以最大程度地减少Go-> C开关的数量。 然后从Go绑定新的C接口。

如果您是从头开始绑定库,那么我将以尽可能最直接的方式使用cgo ,然后查看性能是否满足您的要求。

如果不是这样,请尝试减少您在通常​​称为“斑点”中进行的C调用次数。 正如您在问题中已经提到的那样,Go进行C调用时会切换到另一个堆栈,如果您对琐碎的函数进行大量cgo调用,这将影响性能。 因此,提高性能的一种方法是减少C调用的总数。

例如,如果您需要调用多个C函数以在Go API中实现一个操作,请考虑是否可以编写一个小的Shim C函数来组合这些调用。

如果您要包装的API处理了很多字符串,那么在您进行许多调用(例如:

func foo(bar string) {
    cBar := C.CString(bar)
    defer C.free(unsafe.Pointer(cBar)
    C.foo(cBar)
}

这是三个C调用。 如果您要包装的API可以处理未终止的字符串,则此处的一种选择是将指向该字符串的指针传递给包装器,并使用在生成的_cgo_export.h定义的GoString类型。 例如,在转到一侧:

func foo(bar string) {
    C.foo_wrapper(unsafe.Pointer(&bar))
}

在C端:

#include "_cgo_export.h"
void foo_wrapper(void *ptr_to_string) {
    GoString *bar = ptr_to_string;
    foo_with_length(bar->p, bar->n);
}

只要该库不保留foo_wrapper返回时过去的字符串数据,这应该是安全的。

可能还有其他一些优化可能会有所帮助,但是我强烈建议您一开始保持简单,并尽力优化重要领域。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM