转载自:http://blog.csdn.net/caz28/article/details/45972109
有时我们需要大量的数据,一般编个程序生成一堆随机数据,很适合文本处理,干这个很方便。
下面程序生成一千万条数据,空格分开。
# 生成数据库文件,用于测试SQL数据库 # id,firstName(14),lastName(14),birthday,sex import random,datetime import time dataCount = 10*1000*1000 #10M. codeRange = range(ord('a'),ord('z')) alphaRange = [chr(x) for x in codeRange] alphaMax = len(alphaRange) daysMax = 42003 theDay = datetime.date(1900,1,1) def genRandomName(nameLength): global alphaRange,alphaMax length = random.randint(1, nameLength) name = '' for i in range(length): name += alphaRange[random.randint(0,alphaMax-1)] return name def genRandomDay(): global daysMax,theDay mDays = random.randint(0,daysMax) mDate = theDay + datetime.timedelta(days=mDays) return mDate.isoformat() def genRandomSex(): return random.randint(0,1) def genDataBase1(fileName,dataCount): outp = open(fileName,'w') i = 0 while i<dataCount: firstName = genRandomName(14) lastName = genRandomName(14) birthday = genRandomDay() sex = genRandomSex() mLine = "%i %s %s %s %d\n"%(i+1,firstName,lastName,birthday,sex) outp.write(mLine) i += 1 outp.close() if __name__ == "__main__": random.seed() start = time.time() genDataBase1('db_test.txt',dataCount) end = time.time() print('use time:%d'%(end-start)) print('Ok') |
genDatabase.py
一条数据长度随机,平均38个字节左右,总共生成370MB左右的数据文件,用时23分钟左右。
了哪个地方是性能瓶颈,发现用时最长是genRandomName函数,而且每条数据调用两次,第二长的是genRandomDay。
genRandomName 用时是 genRandomDay 的 7倍,genRandomDay 里也没什么可优化的,所以重点优化genRandomName。
在Python中尝试了几种方法:
1.先生成字符列表,再join,而不是用+。
2.用random.sample。
提高速度都不明显,小于10%。
后来发现不做字符串操作,速度也提高有限,random操作看来比较耗时间。
于是写了一个dll,通过ctypes使用,提高速度明显,同样是一千五条,用时8.65分钟。
# 使用C语言库优化字符串生成 # 生成数据库文件,用于测试SQL数据库 # id,firstName(14),lastName(14),birthday,sex import ctypes import random,datetime import time dataCount = 10*1000*1000 #10M. codeRange = range(ord('a'),ord('z')) alphaRange = [chr(x) for x in codeRange] alphaMax = len(alphaRange) daysMax = 42003 theDay = datetime.date(1900,1,1) ss = ctypes.CDLL('c_dll.dll') p = ctypes.create_string_buffer(14+1) def genRandomName(nameLength): global ss,p length = random.randint(1, nameLength) ss.func(p,length) # c函数随机生成length长度的字符串。 name = p.value.decode('ascii') return name def genRandomDay(): global daysMax,theDay mDays = random.randint(0,daysMax) mDate = theDay + datetime.timedelta(days=mDays) return mDate.isoformat() def genRandomSex(): return random.randint(0,1) def genDataBase1(fileName,dataCount): outp = open(fileName,'w') i = 0 while i<dataCount: firstName = genRandomName(14) lastName = genRandomName(14) birthday = genRandomDay() sex = genRandomSex() mLine = "%i %s %s %s %d\n"%(i+1,firstName,lastName,birthday,sex) outp.write(mLine) i += 1 outp.close() if __name__ == "__main__": ss.randomSeed() # c函数rand初始化seed。 random.seed() start = time.time() genDataBase1('db_test.txt',dataCount) end = time.time() print('use time:%d'%(end-start)) ss = None print('Ok') |
genDatabase3.py
c_dll是用c实现的生成任意长度的随机字符串的函数,编译成dll,放到Python程序相同目录下调用。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> int getRand(int max) { int i = rand(); double f = (double)i / (double)(RAND_MAX+1); return (int)(f*(double)max); } void _declspec(dllexport)func(char *p,int len) { int i; for(i=0;i<len;i++) { *(p+i) =(char)('a'+getRand(26)); } *(p+i) = '\0'; } void _declspec(dllexport)randomSeed(void) { srand((unsigned)time(NULL)); } |
genName.c
后来,用c实现的randInt函数代替Python的,用时5.3分钟,相对原来23分钟,速度提高4.34倍。
使用navicat导入mysql的导入向导时注意选择日期分隔符为“-”,否则导入日期均为0000-00-00。
txt加上列名,那么导入向导就从第二行数据开始。其他则均不变。