Auf Thema antworten

Hmja, weiter oben hatte ich ja schon angedeutet, dass für Matrizen und Vektoren bis 3D wohl die Vorteile überwiegen, und als größte Gefahr die schlechtere Performance durch den GC genannt.


BTW:

(als einziges Problem hat sich die Garbage Collection herausgestellt, es sieht aber so aus, als hätte man das inzwischen im Griff)

Jetzt ist nicht klar: HAT es sich als Problem herausgestellt, oder HAT man es im Griff?


Aber wenn das mit dem GC kein Problem mehr ist, ist die Immutable-Lösung natürlich schöner, gerade in Scala. (In Java gibt es das "vecmath" package mit 3D-Primitiven ... schlimm genug, dass dort sowas wie Vector3d mutable ist - die Fields x,y, und z sind auch noch public :noe: )



Aber bei größeren Matrizen können dort eben Probleme auftreten. Und in bezug auf Strassen und Divide & Conquer: Es ging - wie auch bei dem Beispiel mit den Graphen - nicht um ein unmittelbares, konkretes Problem, sondern um die allgemeine Frage, wie man mit großen Datenblöcken umgeht. Und um alles, was damit zusammenhängt (Z.B. dass man dabei durch das "Erstellen veränderter Kopien" leicht an die Grenzen des verfügbaren Speichers stößt, oder wie man z.B. ein Interface für eine funktional zu verwendende (große) Matrix vernünftig definiert)


Aber vielleicht werden meine Hirnknoten sichtbarer, wenn ich mal konkreter werde: Ich hatte mal ganz straighforward hingeschrieben, wie ein Interface für eine generische Matrix aussehen könnte. Und wenn dort eine Methode drinsteht

[code=Java]

GenericMatrix2D<T> set(int r, int c, T t);

[/code]

tauche eben die ersten Fragezeichen auf. Die Sache mit dem Baum mag ja ja formal eine Lösung sein. Die einfachste und "funktionalste" Lösung wäre da wohl die Baumknoten schlicht und einfach wieder als Matizen zu speichern (zumindest in erster Näherung). Aber wenn man die möglichen Implementierungen mal überschlagsweise vergleicht...

[code=Java]

public GenericMatrix2D<T> set(int r, int c, T t)

{

    array[c+r*cols] = t;

    return this;

}

[/code]

vs.

[code=Java]

public GenericMatrix2D<T> set(int r, int c, T t)

{

    // Ein Blatt is einfach eine 1x1-Matrix

    if (size().equals(1,1))

    {   

        return createOneElementMatrixFrom(t);

    }

    GenericMatrix2D<T> result = create();

    int affected = computeAffectedIndex(r,c);


    // Teilbäume/Untermatrizen weiterverwenden

    for (int i=0; i<4; i++)

    {

        result.treeNodes[i] = this.treeNodes[i];

    }


    // Rekursiv bis zu den Blättern runterhangeln

    int localRow = computeRowInTreeNode(affected, r);

    int localCol = computeColInTreeNode(affected, c);

    result.treeNode[affected] = this.treeNode[affected].set(localRow, localCol, t);

    return result;

}

[/code]


Dann ist IMHO klar, was passiert, wenn jemand die Matrix mit

[code]

for (int r=0; r<10000; r++)

{

    for (int c=0; c<10000; c++)

    {

        matrix = matrix.set(r,c,valueFor(r,c));

    }

}

[/code]

mit irgendwelchen Werten füllen will. Man könnte jetzt sagen: Ja, dann muss es eben eine Methode geben wie

Matrix#fillWith(ValueProviderFunction v);

und der Benutzer ist selbst schuld, wenn er "so blöd ist, anzunehmen, dass man in einer Matrix einfach so ein Element setzen kann". Aber so ganz behagt mir das nicht. Ich muss mir wohl wirklich erstmal die Zeit nehmen, da mögliche Strukturen und Implementierungen durchzudenken, vielleicht kommt ja noch der :idea:-Effekt...



Oben