在python中通过调用dll来提高运行速度

这篇具有很好参考价值的文章主要介绍了在python中通过调用dll来提高运行速度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前言

最近项目中需要录制键鼠命令,然后再通过注入的方式回放录制过程。一般来说,普通的一些点击命令完全可以通过python的一些包来完成键鼠模拟操作,比如通过pyautogui包。但是,鼠标移动过程中,如果采用频率很高的话,比如1s之类采样50个点像素坐标,那么就会发现,如果是通过python进行回放的话,整个回放过程,相比于原来的录制过程,就如同慢放一样。
整个过程抽象如下:
在录制过程每隔时间T进行一次采样(记录下该点的坐标),由于采样本身所消耗的时间极少(小于0.1ms),可以忽略,因此,录制过程假如采样n个点,需要的时间为:nT
回放过程,需要依次移动到采样的的每个点p1、p2…,由于在回放过程移动到每个点是通过python函数moveTo来实现的,而函数moveTo执行一次的时间为t(大概在100ms左右,不能忽略),所以回放过程消耗的时间为:nT + nt 。
回放过程与录制过程的时间比比:(nT + nt)/nT = 1 + t/T,因此回放过程相对于录制过程,相当于是1 + t/T倍慢放。并且采样频率越高,即T越小,慢放的比例越大!
在python中通过调用dll来提高运行速度,C++基础知识,python与爬虫,python,c++,python与c++性能对比,python中调用dll,python与动态库
为了让回放过程更加接近录制过程,即减小慢放的比例,就需要缩放moveTo的执行时间。由于通过python实现moveTo的时间消耗较长,可以通过c/c++来实现moveTo,就可以大幅缩短moveTo需要的时间。

2、生成dll

为了在python中调用dll,需要先生成moveTo的dll文件。对应的源码如下:

// mouseMove.h
#ifdef MYDLL_EXPORTS
#define MATH_API __declspec(dllexport)
#else
#define MATH_API __declspec(dllimport)
#endif
#include <windows.h>
extern "C" {
	MATH_API void mouseClick(int x, int y);
	MATH_API void LeftDown(int x, int y);
	MATH_API void LeftUp(int x, int y);
	MATH_API void mouseMove(int x, int y);  // 对应moveTo函数
}
// mouseMove.cpp
void mouseClick(int x, int y) {
	INPUT input = { 0 };
	input.type = INPUT_MOUSE;
	input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;

	// 计算屏幕上的坐标位置
	input.mi.dx = x * 65535 / GetSystemMetrics(SM_CXSCREEN);
	input.mi.dy = y * 65535 / GetSystemMetrics(SM_CYSCREEN);

	SendInput(1, &input, sizeof(INPUT));
}

void LeftDown(int x, int y) {
	INPUT input = { 0 };
	input.type = INPUT_MOUSE;
	input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN;

	// 计算屏幕上的坐标位置
	input.mi.dx = x * 65535 / GetSystemMetrics(SM_CXSCREEN);
	input.mi.dy = y * 65535 / GetSystemMetrics(SM_CYSCREEN);

	SendInput(1, &input, sizeof(INPUT));
}
void LeftUp(int x, int y) {
	INPUT input = { 0 };
	input.type = INPUT_MOUSE;
	input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTUP;

	// 计算屏幕上的坐标位置
	input.mi.dx = x * 65535 / GetSystemMetrics(SM_CXSCREEN);
	input.mi.dy = y * 65535 / GetSystemMetrics(SM_CYSCREEN);

	SendInput(1, &input, sizeof(INPUT));
}
void mouseMove(int x, int y) {
	INPUT input = { 0 };
	input.type = INPUT_MOUSE;
	input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

	// 计算屏幕上的坐标位置
	input.mi.dx = x * 65535 / GetSystemMetrics(SM_CXSCREEN);
	input.mi.dy = y * 65535 / GetSystemMetrics(SM_CYSCREEN);

	SendInput(1, &input, sizeof(INPUT));
}

注意:在dll文件中不仅实现mouseMove(对应moveTo),还顺带实现了mouseClick等操作。

3、通过pyton调用dll

在python中调用dll文件,只需要先导入ctypes包,然后通过ctypes包加载dll文件,然后调用dll中的函数即可。

import ctypes
import pyautogui
# 加载dll文件
lib = ctypes.cdll.LoadLibrary("E:\\program\\cplusplus\\myDll\\x64\\Release\\myDll.dll")
# 调用dll中的函数
lib.mouseMove(100,200)

4、python库与dll库运行速度对比

都知道比速度python肯定是比不上c/c++,但是运行速度到底差了多少呢?如果单纯是就论本问题提到的移动鼠标这个功能的话,说出来可能吓人!!!
无图说个。。。。,

import time
import ctypes
import pyautogui
lib = ctypes.cdll.LoadLibrary("E:\\program\\cplusplus\\myDll\\x64\\Release\\myDll.dll")
t = time.time()
# dll执行1000次mouseMove
for i in range(0,1000):
    lib.mouseMove(i,2)
t1 = time.time()
print("mouseMove 1000 times by dll: ",t1 - t)
# 通过pyautogui执行100次moveTo
t = time.time()
for i in range(0,100):
    pyautogui.moveTo(i,300)
t1 = time.time()
print("moveTo 100 times by pyautogui:",t1 - t)

在python中通过调用dll来提高运行速度,C++基础知识,python与爬虫,python,c++,python与c++性能对比,python中调用dll,python与动态库
从图中可以看到,通过dll执行1000次mouseMove消耗的时间为0.11s,平均一次0.1ms左右
通过pyautogui执行100 mouseTo消耗时间为10s,平均一次消耗时间100ms
居然相差了1000倍???
难怪录制过程转换为python回放都变慢放了~
------------------------- 更新 ------------------------------------
之前一直很难相信python和c++ dll的速度会相差这么,事实上却是也没有这么大的差距,应该本质上pyautogui也是通过调用windows API相关dll。那么问题出在哪里呢?
研究pyautogui源码发现,pyautogui的moveTo接口有装饰器,绝大部分时间都消耗在了装饰器上。
在python中通过调用dll来提高运行速度,C++基础知识,python与爬虫,python,c++,python与c++性能对比,python中调用dll,python与动态库
将装饰器去掉的话,就和调用dll的速度相当了。

参考文章:
【1】python 调用 c++ dll库
【2】C++模拟鼠标移动及单击实现代码
【3】[python] python调用C++ 程序文章来源地址https://www.toymoban.com/news/detail-660878.html

到了这里,关于在python中通过调用dll来提高运行速度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (亲测可行)关于提高IDEA运行速度的方案

    如果idea版本和本文不符,请不要轻易尝试,造成代码丢失,自行负责。 版本: Ultimate 2022.1.2版IDEA,计算机内存为12GB 打开idea,找到左上角的”help“标签,对话框中选择Edit Custom FVM Options… 调节(最小和最大)堆内存(看本机内存来顶,不超过20%):-Xms和-Xmx 调节代码缓存

    2024年01月17日
    浏览(39)
  • Selenium | 你真的知道怎么提高Selenium的运行速度吗?

    对于网上流传的提高selenium的方法有很多,但从程序运行的感官上来看,感觉提速并不明显。所以,我特地做了一些测试,寻找最优方案。 但是,由于对不同组的测试次数并不相同,结果可能不太严谨。但是,一般来说,结果基本都在一定范围内浮动,所以结果和多次测试大

    2024年02月03日
    浏览(47)
  • [Selenium]你真的知道怎么提高Selenium的运行速度吗?

    对于网上流传的提高selenium的方法有很多,但从程序运行的感官上来看,感觉提速并不明显。所以,我特地做了一些测试,寻找最优方案。 但是,由于对不同组的测试次数并不相同,结果可能不太严谨。但是,一般来说,结果基本都在一定范围内浮动,所以结果和多次测试大

    2024年02月06日
    浏览(42)
  • MySQL数据库——MySQL优化服务器,提高MySQL的运行速度!

    MySQL是一种广泛使用的关系型数据库管理系统,优化MySQL服务器可以显著提高数据库的性能和运行速度。在下面的回答中,我将介绍一些常见的MySQL优化策略和技术,以帮助提高MySQL服务器的性能。 1、优化数据库设计: 正确设计数据库结构,使用适当的数据类型、索引和约束

    2024年02月07日
    浏览(69)
  • 三行Python代码,让数据处理速度提高2到6倍

    Python 是机器学习领域内的首选编程语言,它易于使用,也有很多出色的库来帮助你更快处理数据。但当我们面临大量数据时,一些问题就会显现 …… 在默认情况下, Python 程序是单个进程,使用单 CPU 核心执行。而大多数当代机器学习硬件都至少搭载了双核处理器。这意味着

    2023年04月18日
    浏览(40)
  • Python多线程爬虫为何效率低下?解析原因并提高爬虫速度的方法

    线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属的一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建

    2024年02月01日
    浏览(40)
  • python 调用dll 详解

    准备 将动态库与py文件放在同一目录下 引入ctypes库 加载动态库 数据类型 ctypes数据类型 C数据类型 c_char char c_short short c_int int c_long long c_ulong unsigned long c_float float c_double double c_char_p char* c_void_p void* 基本数据类型参数 argtypes :定义函数的参数类型 restype :定义函数的返回值类

    2024年02月14日
    浏览(45)
  • Python调用动态链接库(DLL)

    Python调用动态链接库(DLL) 动态链接库(Dynamic Link Libraries,简称DLL)是一种被多个程序共享的库文件,可以被用于将程序分解为小模块,减少内存占用,加快程序运行速度。而Python作为一种高级编程语言,可以方便地调用外部的DLL文件。 在Python中,可以使用ctypes模块来调用

    2024年02月13日
    浏览(52)
  • visual studio编写DLL,python调用

    选择第一个c++ DLL, 然后项目源文件下右击新建项,这里名字随便取,在代码中输入一下内容: 在visual studio的项目右击属性 选择不使用编译头,然后点击点击生成解决方案 就可以生成DLL文件了 (PS:前面截图代码忘记添加EXPORT,请参考代码框的代码) 然后python调用即可 如果

    2024年02月09日
    浏览(48)
  • Python如何调用DLL库?——实例详解及代码

    Python如何调用DLL库?——实例详解及代码 在Python中,您可以通过调用DLL库完成各种功能,来满足不同的需求。调用DLL库意味着从外部获取了一些函数,可以在Python中直接调用这些函数,这对于Python程序员来说是一种非常有用的技能。本文将为大家介绍如何在Python中调用DLL库。

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包