Here's some pieces of my thoughts on optimization. I could do more if I knew what the cone-related calculations looked like.
The point is to do as much as possible
only once instead of each time through the looping.
(I'm first going to post this in C# because that's how I think, and then I'll add a slightly cleaned up decompilation into VB!)
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Media.Media3D;
namespace Stuff
{
class Program
{
static void Main(string[] args){ }
class Thing : IComparable<Thing>
{
private static readonly Vector3DConverter V3Parser = new Vector3DConverter();
public Thing(Vector3D raw)
{
_Raw = raw;
R = _Raw.Length;
Theta = Math.Acos(raw.Z / R);
Phi = Math.Atan2(raw.Y, raw.X);
Q = Phi < -Math.PI / 2 ? 0 :
Phi < 0 ? 1 :
Phi < Math.PI / 2 ? 2 :
3;
}
public Thing(string textual)
: this((Vector3D)V3Parser.ConvertFromString(textual))
{ }
private readonly Vector3D _Raw;
public Vector3D Raw { get { return _Raw; } }
public readonly double R;
public readonly double Theta;
public readonly double Phi;
public readonly int Q;
#region IComparable<Thing> Members
public int CompareTo(Thing other)
{
if (other == null)
throw new ArgumentNullException("other");
return R.CompareTo(other.R);
}
#endregion
public override string ToString()
{
return V3Parser.ConvertToString(_Raw);
}
public static Vector3D operator -(Thing thing1, Thing thing2)
{
return thing1._Raw - thing2._Raw;
}
}
static void ConeProblem(string MyFileName)
{
List<Thing> AllThings = new List<Thing>();
foreach (string line in File.ReadLines(MyFileName))
{
AllThings.Add(new Thing(line));
}
AllThings.Sort();
List<Thing> SelectedThings = new List<Thing>();
for (int i = 0; i < AllThings.Count; i++)
{
Thing ti = AllThings[i];
for (int j = i + 1; j < AllThings.Count; j++)
{
Thing tj = AllThings[j];
if (IsInConeVector(ti, tj))
SelectedThings.Add(tj);
}
}
}
static bool IsInConeVector(Thing t1, Thing t2)
{
if (t1.Q != t2.Q)
return false;
return true;
}
}
}
VB-ish: (retyped, there may be typos)
Import System
Import System.Collections.Generic
Import System.IO
Import System.Windows.Media.Media3D
Private Class Thing
Implements IComparable(Of Thing)
Private Shared ReadOnly V3Parser As Vector3DConverter = New Vector3DConverter
Public Sub New(ByVla textual As String)
Me.New(DirectCast(Thing.V3Parser.ConvertFromString(textual), Vector3D))
End Sub
Public Sub New(ByVal raw as Vector3D)
Me._Raw = raw
Me.R = raw.Length
Me.Theta = Math.Acos(raw.Z / Me.R)
Me.Phi = Math.Atan2(raw, Y, raw.X)
Me.Q = If((Me.Phi < -Math.PI/2), 0,
If((Me.Phi < 0), 1,
If((Me.Phi < Math.PI/2), 2, 3)))
End Sub
Public Function CompareTo(ByVal other As Thing) As Integer
If (other Is Nothing) Then
Throw New ArgumentNullException("other")
End If
Return Me.R.CompareTo(other.R)
End Function
Public Shared Operator -(ByVal thing1 As Thing, ByVal thing2 as Thing) As Vector3D
Return (thing1._Raw - thing2._Raw)
End Function
Public Overrides Function ToString() As String
return Thing.V3Parser.ConvertToString(Me._Raw)
End Function
Public ReadOnly Property Raw As Vector3D
Get
Return Me._Raw
End Get
End Property
Private ReadOnly _Raw As Vector3D
Public ReadOnly Phi As Double
Public ReadOnly Q As Integer
Public ReadOnly R As Double
Public ReadOnly Theta As Double
End Class
Private Shared Sub ConeProblem(ByVal MyFileName As String)
Dim AllThings as New List(Of Thing)
Dim line as String
For Each line In File.ReadLines(MyFileName)
AllThings.Add(New Thing(line))
Next
AllThings.Sort()
Dim SelectedThings As New List(Of Thing)
Dim i As Integer
For i = 0 To AllThings.Count - 1
Dim ti As Thing = AllThings.Item(i)
Dim j As Integer
For j = (i + 1) To AllThings.Count - 1
Dim tj As Thing = AllThings.Item(j)
If Program.IsInConeVector(ti, tj) Then
SelectedThings.Add(tj)
End If
Next j
Next i
End Sub
Private Shared Function IsInConeVector(ByVal t1 As Thing, ByVal t2 As Thing) As Boolean
If (t1.Q <> t2.Q) Then
Return False
End If
Return True
End Function
To further optimize performance (if you have multi-cores available), and memory a bit, setup the writing of the
SelectedThings
in a separate thread (
BackgroundWorker
) and use (something like) a
System.Threading.Concurrent.BlockingCollection
to safely pass the
Thing
s from selection to being written out.