user-0 提问: 为什么我的快速排序算法这么慢？

回复:
user: user-1
content: #include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79   无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

user: user-2
content: 你直接freopen一下，先写好一个全是随机数的文件（PYTHON很方便），再进行测试

user: user-3
content: 这样啊，把随机数写道文件里， 每次读取数据，然后再排序 一次生成永续使用，而且数据生成，和排序测试，可以写成两个独立的程序 是不是简单些 排序程序，其实简单不了多少 大概思路，是不能简单的，能精简的不多。 你可以把测试排序的代码，写成inline 函数，或者宏 然后，直接调用排序测试函数，main 函数，就比较清爽了

user: user-0
content: 引用 31 楼 lm_whales 的回复:随机数生成器，起码要有两个特性 1）不能太均匀，比如奇偶相间排列 2）能够取到，某个范围所有的数值。 嗯嗯，我是说我的程序有点麻烦，能不能简单一点，不是说这个随机数生成函数，你可能理解错了

user: user-3
content: 随机数生成器，起码要有两个特性 1）不能太均匀，比如奇偶相间排列 2）能够取到，某个范围所有的数值。

user: user-4
content: 这么多行，我还真看不出来。

user: user-3
content: const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed = seed + M; return s_seed; }

user: user-3
content: const int A =48271; const int M =2147483647; ///修正一下，2^31-1 =2147483647;

user: user-3
content: 引用 28 楼 HowieZhao 的回复:[quote=引用 22 楼 lm_whales 的回复:] 31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;   这个代码如下：  const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed +=M; return s_seed; }  可以把这个代码封装成类 谢谢啦，还有我觉得我这个程序太麻烦了，能不能改的简单一点？[/quote] 这个是一本书上，经过严格论证的， 我个人感觉已经最简单了 至于伪随机序列生成器（线性同余数生成器），都是有严格数学依据的。 这种生成器，可以生成0～某个范围内的所有数 这里是0～21474836647; 之所以这么麻烦，是为了处理溢出，和负数 这个随机数生成器，不会生成负数，种子也不能有负数。

user: user-5
content: 建议用性能工具分析一下，看主要耗时是在哪些函数，才好具体分析原因

user: user-0
content: 引用 20 楼 qq_35473404 的回复:产生数据范围大一些 关键是如何产生大范围的数据呢？

user: user-0
content: 引用 22 楼 lm_whales 的回复:31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;   这个代码如下：  const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed +=M; return s_seed; }  可以把这个代码封装成类 谢谢啦，还有我觉得我这个程序太麻烦了，能不能改的简单一点？

user: user-0
content: 引用 23 楼 wangyaninglm 的回复:对，我觉得跟数据也有很大关系，另外就是要用profile分析一下的 嗯嗯，还有我觉得我这个程序太麻烦了，能不能改的简单一点？

user: user-6
content: 楼主好早啊，，，佩服，可以用下面简单的方法产生一些大随机数  (rand()*1000)+rand();

user: user-6
content: 引用 24 楼 HowieZhao 的回复:[quote=引用 17 楼 cyfcsd 的回复:] 楼主好早啊，，，佩服，可以用下面简单的方法产生一些大随机数  (rand()*1000)+rand();  但是这个应该很少有可能产生小的数啊，我需要的是范围大的，而不是大的随机数，如果只是大的随机数，那它的范围等于没变多少啊，对吗？还有一个小请求，我看我这个程序太麻烦了，能不能改的简单一点？[/quote] rand()是不会产生很小的数，你可以用(rand()%m*10000)+rand()%n;这种类型的方式，总之是几个随机数相加，应该可以凑出你要的结果的

user: user-0
content: 引用 19 楼 qq_35473404 的回复:可能是你产生的数的范围太小了，你可以看看产生1到2000000的数试试 你说对了，经过检查就是生成数的范围太小了，但是rand()函数最大只能生成3万左右的数啊，有什么办法可以生成1到2000000呢？

user: user-0
content: 引用 17 楼 cyfcsd 的回复:楼主好早啊，，，佩服，可以用下面简单的方法产生一些大随机数  (rand()*1000)+rand();  但是这个应该很少有可能产生小的数啊，我需要的是范围大的，而不是大的随机数，如果只是大的随机数，那它的范围等于没变多少啊，对吗？还有一个小请求，我看我这个程序太麻烦了，能不能改的简单一点？

user: user-0
content: 引用 15 楼 lm_whales 的回复:C++11标准库有新的随机数生成器 并且，你也可以自行定义随机数生成器 ------伪随机序列生成器， 更准确的叫 线性同余数生成器    Unix,Linux 有drand48 函数可用，可以生成32Bits随机数 一些数据结构的书籍里，也有31Bits 随机数生成算法 31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;  32Bits drand48 公式 x[i+1]=(A * x[i]+C)%(2^B)  A =25214903917 B=48 C=13 返回高32Bits    [quote=引用 14 楼 HowieZhao 的回复:] [quote=引用 13 楼 lm_whales 的回复:] 快排，一般采用三数取中法，比采用左边或者右边的作为划分标志。随机性更好 按理说，采用随机算法。效果最好 不过，随机数生成器本身的效率，比较低，实用性并不好 刚刚那个问题已经基本解决了，现在有遇到了一个新问题，不知该如何生成一个大范围的随机数呢？rand()函数生成的最大随机数也只是3万多啊，不够[/quote][/quote] 不好意思，不是很理解

user: user-7
content: 对，我觉得跟数据也有很大关系，另外就是要用profile分析一下的

user: user-3
content: 31Bits x[i+1] =A *x[i] %M A=48271； M =21474836647；  注意处理溢出 处理方式如下： R=M/A; Q=M%A;  x[i+1] =A *(x[i] %Q)-R*(x[i]/Q); if(x[i+1]>=0 ){ } else x[i+1] +=M;   这个代码如下：  const int A =48271; const int M =21474836647; const int R=M/A; const int Q=M%A; static int s_seed=1; srand31b(int seed){     if(seed<0)seed+=M;     s_seed= seed; }  int rand31b(){ int seed =A *(s_seed %Q)-R*(s_seed/Q); if(seed >=0 ){s_seed=seed; } else s_seed +=M; return s_seed; }  可以把这个代码封装成类