• 用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加上列名,那么导入向导就从第二行数据开始。其他则均不变。

  • 相关阅读:
    微服务:整合 Spring Cloud Eureka
    微服务:整合 Spring Cloud Eureka
    微服务:整合 Spring Cloud Eureka
    微服务:整合 Spring Cloud Eureka
    微服务:整合 Spring Cloud Eureka
    [转] oracle 监听
    [转]PowerDesigner 把Comment写到name中 和把name写到Comment中 pd7以后版本可用
    [oracle]创建查看 LOCAL INDEX
    Oracle like '%...%' 优化
    IIS7上设置MIME让其支持android和Iphone的更新下载
  • 原文地址:https://www.cnblogs.com/AmilyWilly/p/6225088.html
Copyright © 2020-2023  润新知