【DLL加载之最难问题】DllImport如何提高调用DLL的速度(用DllImport调用非COM和.Net的DLL) 帮你顶.我遇到要在C#调用.h(.lib)文件,更是郁闷。那位大侠顺便也帮我解决这个问题。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 调用.lib?让他编译成DLL你再调用就行了 不大能快,因为需要进行环境切换和数据编组.如果你需要大量调用同一函数的话,再写一个非托管的DLL,用它来执行1000次的调用,你的.NET只要调用新DLL中的函数一次,这样可能会比较快 这是由于.net其实是通过代理调用你的dll函数的,同意 h_lj(贝塔) 直接通过C#引用是不行的,因为这个DLL不是COM类型的,而是普通C++导出函数DLL再写一个非托管的DLL,用它来执行1000次的调用...这个也是不可能的,我的程序每次调用都要分析返回的数组,再写非托管没有意义,还不如整个重新写真的没有办法了?C#的速度只能如此? 速度都在P/Invoke时数据拷贝上浪费了建议另外写个非托管dll作为包装,减少数据拷贝次数(一次拷贝所有数据) 把 _SrvRecv(uint ip ,out byte[] data,int len)改成unsafe _SrvRecv(uint ip ,out byte* data,int len)试试 指针的方法试验了一下,速度基本没有变化不用指针的话大概是8-10次/秒用指针为参数调用的话,大约是10次/秒(但是我的机器两种情况都绝对不会超过10次)所以还是没有什么用处,似乎不管用不用unsafe指针,系统都要做一个非托管转换,真麻烦我用VC6来调用的话,至少100次/秒是肯定没有问题,现在我这里是严重瓶颈 实在不行,建议用托管/非托管c++的混合方式来调用SrvRecv __gc public class SomeClass { public: SomeMethod(void) { _SrvRecv(ip ,&data,len); .......... } }; 托管C++调用标准DLL函数没有象C#这样的速度问题嘛? 昨日连续测试一夜C++调用280万次C#调用7万次相差太悬殊了,这样以后怎么用C#开发啊 我用C++和C#分别调用kernel32.dll 的CopyMemory100000次,发现两者的时间基本一样,附源码以供参考:C++: LARGE_INTEGER lBegin,lEnd,lCount; void* pSrc=new char[100000]; void* pTag=new char[100000]; QueryPerformanceCounter(&lBegin); for (int i=0;i<100000;i++) { CopyMemory(pTag,pSrc,100000); } QueryPerformanceCounter(&lEnd); lCount.QuadPart = lEnd.QuadPart - lBegin.QuadPart; delete pSrc; delete pTag; printf("%I64d\n", lCount.QuadPart);C#: class Class1 { [DllImport("kernel32", ExactSpelling=true, EntryPoint="RtlMoveMemory", CharSet=System.Runtime.InteropServices.CharSet.Ansi)] public static extern void CopyMemoryA(IntPtr pdst, IntPtr psrc, int cb); [System.Runtime.InteropServices.DllImport("KERNEL32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] private static extern bool QueryPerformanceCounter( [System.Runtime.InteropServices.Out, In] ref long lpPerformanceCount); /// <summary> /// 应用程序的主入口点。 /// </summary> /// [STAThread] static void Main(string[] args) { // // TODO: 在此处添加代码以启动应用程序 // long lBegin,lEnd,lCount; lBegin = 0; lEnd = 0; IntPtr pSrc=Marshal.AllocHGlobal(100000); IntPtr pTag=Marshal.AllocHGlobal(100000); QueryPerformanceCounter(ref lBegin); for (int i=0;i<100000;i++) { CopyMemoryA(pTag,pSrc,100000); } QueryPerformanceCounter(ref lEnd); lCount = lEnd - lBegin; Marshal.FreeHGlobal(pSrc); Marshal.FreeHGlobal(pTag); System.Console.WriteLine("{0}\n", lCount); } 请教 string 时间格式化写法 如何识别图片中的文字 c#开发的WEB程序或WinForm程序能否在android上运行? 递归的取值问题。 .net服务器配置问题,aspx页面访问不了,asp和html都可以访问 快来抢分:在水晶报表中设置0.00% 这类格式要如何做? C#中的数据库问题 TreeView问题: 当我们鼠标选中一个Node时,只有一种难看的蓝色,请问能够让选中的Node添加其他颜色或不要颜色吗 Math.IEEERemainder 方法 petapoco的问题。 WebForm中使用对话框 弱弱的问,如何……
这个也是不可能的,我的程序每次调用都要分析返回的数组,再写非托管没有意义,还不如整个重新写真的没有办法了?C#的速度只能如此?
建议另外写个非托管dll作为包装,减少数据拷贝次数(一次拷贝所有数据)
不用指针的话大概是8-10次/秒
用指针为参数调用的话,大约是10次/秒
(但是我的机器两种情况都绝对不会超过10次)所以还是没有什么用处,似乎不管用不用unsafe指针,系统都要做一个非托管转换,真麻烦
我用VC6来调用的话,至少100次/秒是肯定没有问题,现在我这里是严重瓶颈
__gc public class SomeClass
{
public:
SomeMethod(void)
{
_SrvRecv(ip ,&data,len);
..........
}
};
C++调用280万次
C#调用7万次相差太悬殊了,这样以后怎么用C#开发啊
C++:
LARGE_INTEGER lBegin,lEnd,lCount;
void* pSrc=new char[100000];
void* pTag=new char[100000];
QueryPerformanceCounter(&lBegin);
for (int i=0;i<100000;i++)
{
CopyMemory(pTag,pSrc,100000);
}
QueryPerformanceCounter(&lEnd);
lCount.QuadPart = lEnd.QuadPart - lBegin.QuadPart;
delete pSrc;
delete pTag;
printf("%I64d\n", lCount.QuadPart);
C#:
class Class1
{
[DllImport("kernel32", ExactSpelling=true, EntryPoint="RtlMoveMemory", CharSet=System.Runtime.InteropServices.CharSet.Ansi)]
public static extern void CopyMemoryA(IntPtr pdst, IntPtr psrc, int cb);
[System.Runtime.InteropServices.DllImport("KERNEL32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool QueryPerformanceCounter( [System.Runtime.InteropServices.Out, In] ref long lpPerformanceCount);
/// <summary>
/// 应用程序的主入口点。
/// </summary>
///
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
long lBegin,lEnd,lCount;
lBegin = 0;
lEnd = 0;
IntPtr pSrc=Marshal.AllocHGlobal(100000);
IntPtr pTag=Marshal.AllocHGlobal(100000);
QueryPerformanceCounter(ref lBegin);
for (int i=0;i<100000;i++)
{
CopyMemoryA(pTag,pSrc,100000);
}
QueryPerformanceCounter(ref lEnd);
lCount = lEnd - lBegin;
Marshal.FreeHGlobal(pSrc);
Marshal.FreeHGlobal(pTag);
System.Console.WriteLine("{0}\n", lCount);
}