谁能把这个程序的性能提升一倍?---并行排序算法
2009-04-21 22:34
218 查看
如下,一组4元矢量的排序,如何把排序时间缩减一半?可以用并行算法。
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Vector4Test
{
public class Vector
{
public double W;
public double X;
public double Y;
public double Z;
public double T;
}
internal class VectorComparer : IComparer<Vector>
{
public int Compare(Vector c1, Vector c2)
{
if (c1 == null || c2 == null)
throw new ArgumentNullException("Both objects must not be null");
double x = Math.Sqrt(Math.Pow(c1.X, 2)
+ Math.Pow(c1.Y, 2)
+ Math.Pow(c1.Z, 2)
+ Math.Pow(c1.W, 2));
double y = Math.Sqrt(Math.Pow(c2.X, 2)
+ Math.Pow(c2.Y, 2)
+ Math.Pow(c2.Z, 2)
+ Math.Pow(c2.W, 2));
if (x > y)
return 1;
else if (x < y)
return -1;
else
return 0;
}
}
internal class VectorComparer2 : IComparer<Vector> {
public int Compare(Vector c1, Vector c2) {
if (c1 == null || c2 == null)
throw new ArgumentNullException("Both objects must not be null");
if (c1.T > c2.T)
return 1;
else if (c1.T < c2.T)
return -1;
else
return 0;
}
}
internal class Program
{
private static void Main(string[] args)
{
Vector[] vectors = GetVectors();
var watch1 = new Stopwatch();
watch1.Start();
A(vectors);
watch1.Stop();
Console.WriteLine("A sort time: " + watch1.Elapsed);
vectors = GetVectors();
watch1.Reset();
watch1.Start();
B(vectors);
watch1.Stop();
Console.WriteLine("B sort time: " + watch1.Elapsed);
vectors = GetVectors();
watch1.Reset();
watch1.Start();
C(vectors);
watch1.Stop();
Console.WriteLine("C sort time: " + watch1.Elapsed);
Console.ReadKey();
}
private static Vector[] GetVectors()
{
int n = 1 << 15;
var vectors = new Vector
;
var random = new Random();
for (int i = 0; i < n; i++)
{
vectors[i] = new Vector();
vectors[i].X = random.NextDouble();
vectors[i].Y = random.NextDouble();
vectors[i].Z = random.NextDouble();
vectors[i].W = random.NextDouble();
}
return vectors;
}
private static void A(Vector[] vectors)
{
Array.Sort(vectors, new VectorComparer());
}
private static void B(Vector[] vectors) {
int n = vectors.Length;
for (int i = 0; i < n; i++)
{
Vector c1 = vectors[i];
c1.T = Math.Sqrt(Math.Pow(c1.X, 2)
+ Math.Pow(c1.Y, 2)
+ Math.Pow(c1.Z, 2)
+ Math.Pow(c1.W, 2));
}
Array.Sort(vectors,new VectorComparer2());
}
private static void C(Vector[] vectors) {
int n = vectors.Length;
for (int i = 0; i < n; i++) {
Vector c1 = vectors[i];
c1.T = Math.Sqrt(c1.X * c1.X
+ c1.Y * c1.Y
+ c1.Z * c1.Z
+ c1.W * c1.W);
}
Array.Sort(vectors, new VectorComparer2());
}
}
}
我晕,刚开始我用的算法A,后来又写了个算法B,我还没用并行算法呢,一看B方法比A方法时间缩短了差不多两个数量级,如下
A sort time: 00:00:00.5346475
B sort time: 00:00:00.0169736
太奇怪了也,难道我的B算法二级缓存命中率比较高?谁能再把我的B方法消耗时间再降低一半,可以用任何语言,Vector类等也可以用自己的数据类型,比如结构啦,四维数组啥的,随意,只要是四元的矢量,每个分量是随机生成的,然后每个矢量的长度是根号下每个分量的平方和,满足这个条件就行。
modify by wawa at 2009-04-22 06:42
应大家回帖要求,
1、把随机数种子初始的语句放到了循环外面
2、每次执行排序重新获取新的乱序Vector
3、把B方法直接对计算出来的double[]排序换成了对对vector[]的排序,因为之前的代码实际上没有对vector[]排序
4、把Vector类增加了值T,用来保存该Vector的长度。
我这里结果如下
A sort time: 00:00:00.6661531
B sort time: 00:00:00.0423115
C sort time: 00:00:00.0302426
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Vector4Test
{
public class Vector
{
public double W;
public double X;
public double Y;
public double Z;
public double T;
}
internal class VectorComparer : IComparer<Vector>
{
public int Compare(Vector c1, Vector c2)
{
if (c1 == null || c2 == null)
throw new ArgumentNullException("Both objects must not be null");
double x = Math.Sqrt(Math.Pow(c1.X, 2)
+ Math.Pow(c1.Y, 2)
+ Math.Pow(c1.Z, 2)
+ Math.Pow(c1.W, 2));
double y = Math.Sqrt(Math.Pow(c2.X, 2)
+ Math.Pow(c2.Y, 2)
+ Math.Pow(c2.Z, 2)
+ Math.Pow(c2.W, 2));
if (x > y)
return 1;
else if (x < y)
return -1;
else
return 0;
}
}
internal class VectorComparer2 : IComparer<Vector> {
public int Compare(Vector c1, Vector c2) {
if (c1 == null || c2 == null)
throw new ArgumentNullException("Both objects must not be null");
if (c1.T > c2.T)
return 1;
else if (c1.T < c2.T)
return -1;
else
return 0;
}
}
internal class Program
{
private static void Main(string[] args)
{
Vector[] vectors = GetVectors();
var watch1 = new Stopwatch();
watch1.Start();
A(vectors);
watch1.Stop();
Console.WriteLine("A sort time: " + watch1.Elapsed);
vectors = GetVectors();
watch1.Reset();
watch1.Start();
B(vectors);
watch1.Stop();
Console.WriteLine("B sort time: " + watch1.Elapsed);
vectors = GetVectors();
watch1.Reset();
watch1.Start();
C(vectors);
watch1.Stop();
Console.WriteLine("C sort time: " + watch1.Elapsed);
Console.ReadKey();
}
private static Vector[] GetVectors()
{
int n = 1 << 15;
var vectors = new Vector
;
var random = new Random();
for (int i = 0; i < n; i++)
{
vectors[i] = new Vector();
vectors[i].X = random.NextDouble();
vectors[i].Y = random.NextDouble();
vectors[i].Z = random.NextDouble();
vectors[i].W = random.NextDouble();
}
return vectors;
}
private static void A(Vector[] vectors)
{
Array.Sort(vectors, new VectorComparer());
}
private static void B(Vector[] vectors) {
int n = vectors.Length;
for (int i = 0; i < n; i++)
{
Vector c1 = vectors[i];
c1.T = Math.Sqrt(Math.Pow(c1.X, 2)
+ Math.Pow(c1.Y, 2)
+ Math.Pow(c1.Z, 2)
+ Math.Pow(c1.W, 2));
}
Array.Sort(vectors,new VectorComparer2());
}
private static void C(Vector[] vectors) {
int n = vectors.Length;
for (int i = 0; i < n; i++) {
Vector c1 = vectors[i];
c1.T = Math.Sqrt(c1.X * c1.X
+ c1.Y * c1.Y
+ c1.Z * c1.Z
+ c1.W * c1.W);
}
Array.Sort(vectors, new VectorComparer2());
}
}
}
我晕,刚开始我用的算法A,后来又写了个算法B,我还没用并行算法呢,一看B方法比A方法时间缩短了差不多两个数量级,如下
A sort time: 00:00:00.5346475
B sort time: 00:00:00.0169736
太奇怪了也,难道我的B算法二级缓存命中率比较高?谁能再把我的B方法消耗时间再降低一半,可以用任何语言,Vector类等也可以用自己的数据类型,比如结构啦,四维数组啥的,随意,只要是四元的矢量,每个分量是随机生成的,然后每个矢量的长度是根号下每个分量的平方和,满足这个条件就行。
modify by wawa at 2009-04-22 06:42
应大家回帖要求,
1、把随机数种子初始的语句放到了循环外面
2、每次执行排序重新获取新的乱序Vector
3、把B方法直接对计算出来的double[]排序换成了对对vector[]的排序,因为之前的代码实际上没有对vector[]排序
4、把Vector类增加了值T,用来保存该Vector的长度。
我这里结果如下
A sort time: 00:00:00.6661531
B sort time: 00:00:00.0423115
C sort time: 00:00:00.0302426
相关文章推荐
- 谁能把这个程序的性能提升一倍?---并行排序算法
- 提升 .NET 程序性能的 一些 原则
- 提升性能 Java程序优化的一些最佳实践
- Visual C++利用Intel C++ 编译器提升多核性能与多媒体指令支持获取更高的程序效率与缩小程序体积
- 使用 OpCache 提升 PHP 5.5+ 程序性能
- Visual C++利用Intel C++ 编译器提升多核性能与多媒体指令支持获取更高的程序效率与缩小程序体积
- 用工具提升程序的性能和稳定性
- 提升性能 Java程序优化的一些最佳实践
- C#程序性能提升篇2 类型(字段类型、class和struct)的错误定义所影响性能浅析
- 数据库性能优化三:程序操作优化提升性能
- final 修饰符能提升 Java 程序的性能吗
- 在细节上提升你的程序的性能
- [转]微小改动提升程序性能
- 提升Java桌面客户端程序性能
- 内存地址对齐提升程序性能
- 使用绑定变量提升 PL/SQL 程序性能
- [编写高质量代码:改善java程序的151个建议]建议132 提升JAVA性能的基本方法
- 微小改动提升程序性能
- Function.apply()在提升程序性能方面的技巧
- 提升 .NET 程序性能的 一些 原则