.版本 2
.程序集 窗口程序集1
.子程序 __启动窗口_创建完毕
.局部变量 info, SYSTEM_INFO
.局部变量 核心数, 整数型
g_ProcessHeap = GetProcessHeap ()
标题 = “生成数据 ” + 取执行文件名 ()
GetSystemInfo (info) ' CPU密集型 取一下CPU核心数
核心数 = 选择 (info.dwNumberOrfProcessors < 1, 4, info.dwNumberOrfProcessors)
编辑框_线程数.内容 = 到文本 (核心数)
.子程序 随机生成多行TXT
.参数 行数
.参数 路径, 文本型
.局部变量 倍数, 整数型
.局部变量 余数, 整数型
.局部变量 temp, LARGE_INTEGER
g_文件_文件号 = CreateFileA (路径, -1073741824, 0, 0, 4, 134217728, 0)
' g_文件_文件号 = 打开文件 (路径, #改读, #无限制)
.如果真 (g_文件_文件号 < 1)
信息框 (“打开文件失败”, 48, , )
返回 ()
.如果真结束
NtQuerySystemTime (temp)
g_Seed = g_文件_文件号 + 到整数 (temp.QuadPart) ' 初始化一个种子
SetFilePointer (g_文件_文件号, 0, 0, 2) ' 移到文件尾
' 移到文件尾 (g_文件_文件号)
g_当前线程数 = 0 ' 置一下零
' 分配每个线程要生成的行数 这儿蛮有意思的吧
倍数 = 行数 \ g_最大线程数
余数 = 行数 % g_最大线程数
.计次循环首 (余数, )
CloseHandle (CreateThread (0, 0, &Func, 倍数 + 1, 0, 0))
InterlockedIncrement_int (g_当前线程数)
.计次循环尾 ()
.计次循环首 (g_最大线程数 - 余数, )
CloseHandle (CreateThread (0, 0, &Func, 倍数, 0, 0))
InterlockedIncrement_int (g_当前线程数)
.计次循环尾 ()
.判断循环首 (InterlockedCompareExchange_int (g_当前线程数, 0, 0) ≠ 0) ' 利用win提供的CAS实现自旋
延时 (1)
处理事件 ()
.判断循环尾 ()
CloseHandle (g_文件_文件号)
' 关闭文件 (g_文件_文件号)
.子程序 Func
.参数 本线程行数, 整数型
.局部变量 倍数, 整数型
.局部变量 余数, 整数型
.局部变量 内存大小, 整数型
.局部变量 Heap, 整数型
.局部变量 i, 整数型
.局部变量 j, 整数型
.局部变量 字符表, 文本型, , "0"
.局部变量 字符表长度, 整数型
.局部变量 tempInt, 整数型
.局部变量 单行长度, 整数型
.局部变量 分块行数, 整数型
置随机数种子 (InterlockedIncrement_int (g_Seed)) ' 初始化一下种子 并且利用原子函数确保每条线程的种子不同
' // 取随机数() 这个命令多线程支持好像比较差 我曾经在论坛发过的翻译过来的MT19937算法,随机率保证,速度会慢一些
' // 当然 还有一些汇编取随机数的 的确快不少 我这儿没用
' rand.reset (InterlockedIncrement_int (g_Seed)) ' 初始化一下种子 并且利用原子函数确保每条线程的种子不同
单行长度 = g_单行长度 ' 多线程读共享变量的系统原理我不太清楚,安全上应该是没啥问题,但速度上也许会有影响.会继续查资料
分块行数 = g_分块行数
字符表 = g_字符表
字符表长度 = 取数组成员数 (字符表)
' rand.setMaxAndMin (1, 字符表长度)
倍数 = 本线程行数 \ 分块行数
余数 = 本线程行数 % 分块行数
.如果真 (倍数 > 0)
内存大小 = (单行长度 + 2) × 分块行数 ' #换行符 长度2
Heap = HeapAlloc (g_ProcessHeap, 0, 内存大小) ' 大小一致 不需要重新分配内存 覆盖写入就好了
.计次循环首 (倍数, i)
tempInt = Heap
.计次循环首 (分块行数, j)
' 看过几篇文章称乘法比加法慢很多 所以弄个中间变量 少计算乘法 还有人说易语言的循环有很多多余的汇编代码 所以也不用计次循环了
RtlMoveMemory (tempInt, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 1, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 2, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 3, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 4, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 5, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 6, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 7, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 8, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 9, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 10, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 11, #换行符, 2)
tempInt = tempInt + 13
.计次循环尾 ()
g_文件_许可证.进入 ()
' 写出字节集 (g_文件_文件号, 指针到字节集 (Heap, 内存大小))
WriteFile (g_文件_文件号, Heap, 内存大小, 0, 0) ' 直接写指针
g_文件_许可证.退出 ()
.计次循环尾 ()
.如果真结束
.如果真 (余数 > 0)
内存大小 = (单行长度 + 2) × 余数
.如果真 (Heap ≤ 0) ' 同样不需要收缩了 反正这个肯定比上面的小
Heap = HeapAlloc (g_ProcessHeap, 0, 内存大小)
.如果真结束
tempInt = Heap
.计次循环首 (余数, j)
RtlMoveMemory (tempInt, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 1, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 2, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 3, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 4, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 5, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 6, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 7, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 8, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 9, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 10, 字符表 [取随机数 (1, 字符表长度)], 1)
RtlMoveMemory (tempInt + 11, #换行符, 2)
tempInt = tempInt + 13
.计次循环尾 ()
g_文件_许可证.进入 ()
' 写出字节集 (g_文件_文件号, 指针到字节集 (Heap, 内存大小))
WriteFile (g_文件_文件号, Heap, 内存大小, 0, 0) ' 直接写指针
g_文件_许可证.退出 ()
.如果真结束
.如果真 (Heap > 0)
HeapFree (g_ProcessHeap, 0, Heap) ' 释放内存
.如果真结束
InterlockedDecrement_int (g_当前线程数)
.子程序 Main
.局部变量 time1, LARGE_INTEGER
.局部变量 time2, LARGE_INTEGER
' 换行分隔符: #换行符
g_行数 = 到整数 (编辑框_行数.内容)
g_字符表 = { “J”, “Y”, “L”, “T”, “&”, “$”, “7”, “|”, “<”, “~”, “?” } ' 字符表中都是半角单字符 也就是长度都为1
g_单行长度 = 11
g_路径 = 取运行目录 () + “\mytest.txt”
删除文件 (g_路径) ' 删除一下,排除已存在的大文件对CreateFile的影响(我也不知道有没有影响)
g_分块行数 = 到整数 (编辑框_分块.内容) ' 防止内存开销太大,同时消耗的内存 ≈ 分块行数 * ( 单行长度 + 2 ) * 最大线程数
g_最大线程数 = 到整数 (编辑框_线程数.内容)
QueryPerformanceCounter (time1)
随机生成多行TXT (g_行数, g_路径) ' 作业代码
QueryPerformanceCounter (time2)
Log.加入文本 (“>>>”, 字符 (9), “用户名:”, 字符 (9), “junkboy”, 字符 (9), 字符 (9), 取执行文件名 (), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “当前为:”, 字符 (9), 选择 (是否为调试版 (), “调试模式”, “编译模式”), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “总行数:”, 字符 (9), 到文本 (g_行数), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “耗时: ”, 字符 (9), 到文本 (时间_高精度计时_api (time1, time2)), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “大小: ”, 字符 (9), 到文本 (取文件尺寸 (g_路径)), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “线程数:”, 字符 (9), 到文本 (g_最大线程数), #换行符)
Log.加入文本 (“>>>”, 字符 (9), “分块: ”, 字符 (9), 到文本 (g_分块行数), #换行符)
Log.加入文本 (#换行符)
连续赋值 (假, 按钮1.禁止, 编辑框_行数.禁止, 编辑框_线程数.禁止, 编辑框_分块.禁止)
.子程序 _按钮1_被单击
连续赋值 (真, 按钮1.禁止, 编辑框_行数.禁止, 编辑框_线程数.禁止, 编辑框_分块.禁止)
CloseHandle (CreateThread (0, 0, &Main, 0, 0, 0))
.子程序 时间_高精度计时_api, 双精度小数型, 公开
.参数 count1, LARGE_INTEGER
.参数 count2, LARGE_INTEGER
.局部变量 Freq, LARGE_INTEGER
QueryPerformanceFrequency (Freq)
返回 ((count2.QuadPart ÷ Freq.QuadPart - count1.QuadPart ÷ Freq.QuadPart) × 1000)