首页 \ 问答 \ 在jQuery中,要选择节点的第n个兄弟节点,是.next()链接n次还是.nextAll(':eq(n-1)')更快?(In jQuery, to select the nth sibling of a node, is .next() chained n times or .nextAll(':eq(n-1)') faster?)

在jQuery中,要选择节点的第n个兄弟节点,是.next()链接n次还是.nextAll(':eq(n-1)')更快?(In jQuery, to select the nth sibling of a node, is .next() chained n times or .nextAll(':eq(n-1)') faster?)

假设节点有任意数量的兄弟节点,并且我想选择该节点的nth sibling节点,我应该使用.next()链接n次,还是应该只使用一次调用.nextAll(':eq(n-1)')

似乎前者对于大n会有很多额外的开销,并且对于大量的兄弟姐妹来说可能是后者的更大开销。 我关心一个涉及n = 2和大量兄弟姐妹的案例,所以我不确定我是否要使用.next().next().nextAll(':eq(1)') 。 有关系吗?

编辑:对于n = 2和许多兄弟姐妹的情况,它看起来像.next().next()是最快的根据http://jsperf.com/next-next-vs-nextall-eq-​​1-vs- nextall-EQ-1


Assuming there are an arbitrary number of siblings of a node, and I wanted to select the nth sibling of that node, should I be using .next() chained up n times, or should I just use a single call to .nextAll(':eq(n-1)')?

Seems like there would be a lot of extra overhead with the former for large n, and possibly a bigger overhead with the latter for large number of siblings. I'm concerned with a case that involves n=2 and a large number of siblings, so I'm not sure if I want to use .next().next() or .nextAll(':eq(1)'). Does it matter?

Edit: For the case of n=2 and many siblings, it looks like .next().next() is fastest according to http://jsperf.com/next-next-vs-nextall-eq-1-vs-nextall-eq-1


原文:https://stackoverflow.com/questions/11961695
更新时间:2024-01-13 15:01

最满意答案

直接从C#使用本机C ++类在技术上是可行的,但它并不是微不足道的,而且它甚至都不是一个好主意。 对于初学者,您必须知道用于从DLL导入的名称,这将是C ++名称修改后的名称。 您也无法直接访问C#中的vector等内容。

基本上有两个不错的选择:

第一种是使用C接口编写DLL,该接口仅使用可以编组为CLR类型的类型。 您可以将指针与IntPtr类型一起使用,但是您无法真正取消引用这些指针。 您几乎可以将它们存储在C#代码中,然后在需要时将它们传递回本机DLL。 只要您不需要深层复制来处理它们,您也可以使用简单的struct类型。 此选项涉及使用P / Invoke。

第二个选项是编写混合模式C ++ / CLI程序集,该程序集实现了访问本机代码所需的所有逻辑。 这个程序集可以直接访问C#代码中的类和数据,也可以直接访问您的本机代码,尽管您应该预先警告,有些烦人的中断,您不能将它们混合在一起。 例如,C ++ / CLI中的ref class不能具有shared_ptr成员。 但是,它可以将原始C ++指针作为成员。 (混合模式)本机类也可以访问CLR句柄类型,并通过它调用C#代码。 此选项涉及使用C ++ Interop。

值得注意的是,你也可以采用C ++ Interop的另一种方式。 您可以让C#代码访问混合模式C ++ / CLI程序集,该程序集为某些本机代码提供.NET接口。 但是,在这种情况下,您仍然需要进行一些翻译,因此它并不比第一个选项好很多。

关于C ++ Interop的完整教程将会相当冗长。 我建议你在这里阅读并对Google上的C ++ Interop做进一步的调查。


In order to make a C wrapper for a C++ class to be used in for example a C# application you can do the following.

In Visual Studio choose Win32 Console Application and Enter a name, Then click next and on the next pane choose DLL and click finish. When you are done you are represented with a DLL project including 3 files.

testdll.h 
testdll.cpp
dllmain

Delete everything that exists inside your testdll.h and testdll.cpp files and copy the following contents to each respectively. Add these lines to your testdll.h

// Our C wrapper for creating a dll to be used in C# apps

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the TESTDLL_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// TESTDLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef  TESTDLL_EXPORTS
#define  TESTDLL_API __declspec(dllexport)
#else
#define  TESTDLL_API __declspec(dllimport)
#endif

extern "C"
{
     TESTDLL_API int OurTestFunction(int x, int y);                         
}

It is inside this extern "C" block where you define your interface, functions to access your class member functions.Note the TESTDLL before the function prototype. All of your functions must be proceeded by that.

Add these to your testdll.cpp file:

#include "testdll.h"
#include "ourClass.h"

#define DLL_EXPORT

extern "C"
{
    OurClass ourObject;
    TESTDLL_API int OurTestFunction(int x, int y)
    {
        return ourObject.Add(x,y);
    }
}

You compile this and get a C based dll which can be used in a C# application.
There are couple of things to notice though, The more important ones are:

  1. You need to understand that the code you use as a proxy- i mean function definition inside your testdll.h, must only use C compatible types, it is C after all not C++.
  2. is that you would want to be able to allocate new objects of your class instead of just using one global object to access all methods.

For this, if you need to pass your class objects between member functions, you need to first convert it to a void* which C can understand and then pass it and use it to access your member functions of whatever.

For example I would have something like this inside my testdll.h in order to make user capable of managing the objects indirectly:

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif

extern "C"
{
    TESTDLL_API int OurTestFunction(int x, int y);                      

    TESTDLL_API void*  CreateHandle();
    TESTDLL_API void*  GetCurrentHandle();
    TESTDLL_API void   DisposeCurrentHandle();
    TESTDLL_API void   SetCurrentHandle(void* handle);
    TESTDLL_API void*  GetHandle();
    TESTDLL_API void   DisposeHandle(void*);
    TESTDLL_API void   DisposeArrayBuffers(void);
}

And inside my testdll.cpp I would define them as :

#include "testdll.h"
#include "ourClass.h"

#define DLL_EXPORT

extern "C"
{
    OurClass *ourObject;

    TESTDLL_API int OurTestFunction(int x, int y)
    {
        //return ourObject.Add(x,y); -- not any more !!
        ourObject = reinterpret_cast<OurClass *>(GetHandle());
    }

    //Handle operations
    TESTDLL_API void* CreateHandle()
    {
        if (ourObject == nullptr)
        {
            ourObject = new OurClass ;
        }
        else
        {
            delete ourObject ;
            ourObject = new OurClass ;
        }
        return reinterpret_cast<void*>(ourObject);
    }

    TESTDLL_API void* GetCurrentHandle()
    {
        return reinterpret_cast<void*>(ourObject );
    }

    TESTDLL_API void  DisposeCurrentHandle()
    {
        delete ourObject ;
        ourObject = nullptr;
    }

    TESTDLL_API void  SetCurrentHandle(void* handle)
    {
        if (handle != nullptr)
        {
            ourObject = reinterpret_cast<OurClass *>(handle);
        }
        else
        {
            ourObject = new OurClass ;
        }

    }

    //factory utility function
    TESTDLL_API void* GetHandle()
    {
        void* handle = GetCurrentHandle();
        if (handle != nullptr)
        {
            return handle;
        }
        else
        {
            ourObject = new OurClass ;
            handle = reinterpret_cast <void*>(ourObject );
        }
        return handle;
    }

    CDLL_API void  DisposeHandle(void* handle)
    {
        OurClass * tmp = reinterpret_cast<OurClass *>(handle);
        delete tmp;
    }

    TESTDLL_API void DisposeArrayBuffers(void)
    {
        ourObject = reinterpret_cast<OurClass *>(GetHandle());
        return ourObject ->DisposeBuffers();//This is a member function defined solely for this purpose of being used inside this wrapper to delete any allocated resources by our class object.
    }
}

And when we compile this Dll, we can easily work with it inside our C# application. Before being able to use our functions defined in this dll we need to use appropriate [ImportDll()]. So for our TestDll we would write:

[DllImport(@"TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int OurTestFunction(int firstNumber,int secondNumber); 

And finally use it like:

private void btnReadBigram_Click(object sender, EventArgs e)
{
    int x = OurTestFunction(10,50);
    MessageBox.Show(x.ToString());
}

This is all I did to make my C++ class member functions accessible inside a C# application without any hassle.

Note:
When compiling your C# application make sure you have chosen the x86 Platform for compiling your project not AnyCpu.You can change your platform through properties.

Note 2:
For knowing how to create a C++/CLI wrapper for your native C++ class read this: C++/CLI wrapper for your native C++ class.

相关问答

更多

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)