python 迭代器 生成器 装饰器

这篇文档较好的解释了生成器的应用原理: 参考,并借斐波那契数列的生成较好的演示生成器与迭代器使用方法

不同于定义好一个完整的 list 再通过迭代器来遍历,通过生成器来实时生成每次要使用的元素,可以最大限度的节省内存。

关于装饰器的概念用使用场景,知乎这篇文章里已有说明:参考

机器学习框架之 scikit-learn Mars

阿里技术公众号上看到这篇文章:链接
内容关于借助Mars使用GPU做加速运算,觉得很受用。这里简单记下环境的配置。

各组件背影关系: numpy 作为基础,在其上,有 scipy 面向科学家,pandas 面向数据分析,scikit-learn 则是最著名的机器学习库,matplotlib 专注于可视化。

存在的问题:PyData 技术栈给数据科学家们提供了多维矩阵、DataFrame 上的分析和计算能力、基于二维矩阵的机器学习算法,这些库都仅仅受限于单机运算,在大数据时代,数据量一大,这些库的处理能力都显得捉襟见肘。在深度学习领域,ndarray/tensor 也是最基本的数据结构,但它们仅仅限制在深度学习上,也不适合大规模的多维矩阵运算。(参考)

Mars 这个库是阿里发起的一个开源项目,一个基于 tensor 的统一分布式计算框架。

组件安装:
pip install scikit-learn 专门面向机器学习的Python开源框架,简介
pip install pymars
pip install tensorflow
pip install cupy

关于提升代码运算效率的几点心得

  1. 硬件方面:
    CPU的主频,睿频要高(保证CPU散热),
    高频内存组双通道,主板开启XMP给内存超频
    显卡(可以的话用显卡做数值运算)

  2. 代码方面:
    使用连接池来连接数据库,降低在连接建立方面的开销(包含但不限于:进程数,端口数,网络通信握手),同时也能降低数据库连接压力
    尽量减少硬盘IO读写,能在内存里进行的操作一定不要用硬盘实现
    离散数据可考虑先缓存,达到一定阀值后再统一写入
    算法也很重要,好的算法可以减少很多运算时间

python 使用连接池 连接 mysql

问题
当我们在Python中连接Mysql时,每次增、删、改、查如果都申请一个数据库连接的话,当应用程序对mysql数据库请求量大时候,运行Python的机器就会大量报time  wait(我碰到的是40000+) 。这是因为每次连接mysql数据库请求时,都是独立的去请求访问(看到开发者的代码后得出结论),相当浪费资源,访问数量达到一定量时 ,运行程序的机器就报警了。

解决办法:
访问数据库应该使用连接池,来达到复用数据库连接的目的

python数据库连接池使用方法:
   a、安装 DBUtils(这里是DBUtils-1.3.tar.gz包)

   b、tar -zxvf DBUtils-1.3.tar.gz

   c、cd DBUtils-1.3

   d、 python setup.py install (安装)

连接示例:
https://yq.aliyun.com/articles/619548?utm_content=m_1000008987

参考链接:https://www.jianshu.com/p/c5a8cccecf32

MySQL挑战:建立10万连接

连接池操作示例:
https://zhuanlan.zhihu.com/p/61050785

安装 DBUtils:
pip install DBUtils -i https://pypi.tuna.tsinghua.edu.cn/simple

代码示例:

import pymysql
from DBUtils.PooledDB import PooledDB

'''
PooledDB() 参数含义

creator:使用链接数据库的模块
maxconnections:连接池允许的最大连接数,0和None表示没有限制
mincached:初始化时,连接池至少创建的空闲的连接,0表示不创建
maxcached:连接池空闲的最多连接数,0和None表示没有限制
maxshared:连接池中最多共享的连接数量,0和None表示全部共享,ps:其实并没有什么用,因为pymsql和MySQLDB等模块中的threadsafety都为1,所有值无论设置多少,_maxcahed永远为0,所以永远是所有链接共享
blocking:链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
setsession:开始会话前执行的命令列表
ping:ping Mysql 服务端,检查服务是否可用
'''
global_pool = PooledDB(
    creator=pymysql,
    maxconnections=500,
    mincached=0,
    maxcached=20,
    maxshared=0,
    blocking=True,
    setsession=[],
    ping=5,
    host=global_db_addr,
    port=3306,
    user='xxxx',
    password='xxxxxx',
    database='xxxxx',
    charset='utf8mb4')

# 以后每次需要数据库连接用 connection() 函数获取连接即可
conn = global_pool.connection()

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = conn.cursor()

#sql = 'INSERT INTO ' + tbl_name + ' (`time_key`,`code`,`direct`) VALUES (%s, %s, %s);'
#params = (dic_data["time_key"], dic_data["code"], dic_data["direct"])

tbl_name = 'stock_cur_kline_sh'
stock_code = 'SH.600161'
time_key = '2020-02-28 00:00:00'

sql = "SELECT Close FROM " + tbl_name + " where code = '" + stock_code + "' and time_key = '" + time_key + "';"

try:
    # 执行SQL语句
    cursor.execute(sql)
    # 获取所有记录列表
    results = cursor.fetchall()
    for row in results:
        close = row[0]
        # 打印结果
        print("close=%f" %(close))
except Exception as e:
    print("插入数据库异常, msg=%s" % (e))
    logging.error(traceback.format_exc())
finally:
    print("插入数据库成功")
    cursor.close()
    conn.close()

pymysql.connect() 参数含义

host=None,          # 要连接的主机地址
user=None,          # 用于登录的数据库用户
password='',        # 密码
database=None,      # 要连接的数据库
port=0,             # 端口,一般为 3306
unix_socket=None,   # 选择是否要用unix_socket而不是TCP/IP
charset='',         # 字符编码
sql_mode=None,      # Default SQL_MODE to use.
read_default_file=None, # 从默认配置文件(my.ini或my.cnf)中读取参数
conv=None,          # 转换字典
use_unicode=None,   # 是否使用 unicode 编码
client_flag=0,      # Custom flags to send to MySQL. Find potential values in constants.CLIENT.
cursorclass=,       # 选择 Cursor 类型
init_command=None,  # 连接建立时运行的初始语句 
connect_timeout=10, # 连接超时时间,(default: 10, min: 1, max: 31536000)
ssl=None,           # A dict of arguments similar to mysql_ssl_set()'s parameters.For now the capath and cipher arguments are not supported. 
read_default_group=None, # Group to read from in the configuration file.
compress=None,      # 不支持
named_pipe=None,    # 不支持
no_delay=None,      # 
autocommit=False,   # 是否自动提交事务
db=None,            # 同 database,为了兼容 MySQLdb
passwd=None,        # 同 password,为了兼容 MySQLdb
local_infile=False, # 是否允许载入本地文件
max_allowed_packet=16777216, # 限制 `LOCAL DATA INFILE` 大小
defer_connect=False, # Don't explicitly connect on contruction - wait for connect call.
auth_plugin_map={}, #
read_timeout=None,  # 
write_timeout=None, 
bind_address=None   # 当客户有多个网络接口,指定一个连接到主机

其它常用函数的用法讲解:
https://blog.csdn.net/memoryd/article/details/74995651

OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次

解决方案参考资料:
https://blog.csdn.net/qq_22520587/article/details/62454317
https://blog.csdn.net/iteye_1485/article/details/82513443?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

可能的原因:
服务器端口被占满,下次通信无空闲端口可用,程序就抛出了“通常每个套接字地址 (协议/网络地址/端口)只允许使用一次”的异常。

1、你的服务器开启的端口数太少;
2、连接释放等待时间太长;
3、你的socket通信并发量太大。
以上几点导致你服务器端口被占满,下次通信无空闲端口可用,程序就抛出了“通常每个套接字地址 (协议/网络地址/端口)只允许使用一次”的异常。

pycuda安装

pip install numba -i https://pypi.tuna.tsinghua.edu.cn/simple

先决条件:
1.要先安装 NVIDIA 官网中,cuda 的程序包:cuda_10.2.89_441.22_win10.exe
1.1 下载网址:https://developer.nvidia.com/cuda-downloads?target_os=Windows&amp%253Btarget_arch=x86_64&amp%253Btarget_version=10%255C&target_arch=x86_64
1.2 安装cuda的时候,不能选中 cuda下的vs,否则会报安装失败

2.要安装 cuda 程序包,前提是要安装 visual studio, 这次安装的是2017 社区版

上面2条先决条件弄好之后,下面这条命令就能成功安装:
pip install pycuda -i https://pypi.tuna.tsinghua.edu.cn/simple

参考文档:
https://blog.csdn.net/qq_32751937/article/details/83084804
结合 N卡官网:https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=7

https://blog.csdn.net/chantor7/article/details/79182848