用Python生成测试数据

转载自:http://blog.csdn.net/caz28/article/details/45972109

有时我们需要大量的数据,一般编个程序生成一堆随机数据,Python很适合文本处理,干这个很方便。

下面程序生成一千万条数据,空格分开。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
# 生成数据库文件,用于测试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 "%(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')
 来自CODE的代码片
genDatabase.py

一条数据长度随机,平均38个字节左右,总共生成370MB左右的数据文件,用时23分钟左右。

测试了哪个地方是性能瓶颈,发现用时最长是genRandomName函数,而且每条数据调用两次,第二长的是genRandomDay。

genRandomName 用时是 genRandomDay 的 7倍,genRandomDay 里也没什么可优化的,所以重点优化genRandomName。

在Python中尝试了几种方法:

1.先生成字符列表,再join,而不是用+。

2.用random.sample。

提高速度都不明显,小于10%。

后来发现不做字符串操作,速度也提高有限,random操作看来比较耗时间。

于是写了一个C语言dll,通过ctypes使用,提高速度明显,同样是一千五条,用时8.65分钟。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
# 使用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 "%(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')
 来自CODE的代码片
genDatabase3.py

c_dll是用c实现的生成任意长度的随机字符串的函数,编译成dll,放到Python程序相同目录下调用。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
#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) = '';
}
 
void _declspec(dllexport)randomSeed(void)
{
srand((unsigned)time(NULL));
}
 来自CODE的代码片
genName.c

后来,用c实现的randInt函数代替Python的,用时5.3分钟,相对原来23分钟,速度提高4.34倍。

使用navicat导入mysql的导入向导时注意选择日期分隔符为“-”,否则导入日期均为0000-00-00。

txt加上列名,那么导入向导就从第二行数据开始。其他则均不变。

原文地址:https://www.cnblogs.com/AmilyWilly/p/6225088.html