zoukankan      html  css  js  c++  java
  • 谁能把这个程序的性能提升一倍?并行排序算法

    如下,一组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[n];
                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

  • 相关阅读:
    Linux下Maven的安装与使用
    Vue1.0用法详解
    一个异步访问redis的内存问题
    jquery和zepto的异同
    我的学习归纳方法(以学习Maven为例)
    最显而易见的设计最容易成功
    Linux Command Backup
    Turn and Stun server · J
    Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名
    Leetcode 981. Time Based Key-Value Store(二分查找)
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/1440829.html
Copyright © 2011-2022 走看看