Hi all
S. hat keine Möglichkeit für uns optimierte Datenbausteine so flexibel zu verwenden wie es mit ANY, AUF DI, AR2 und AWL bei standard Datenbausteinen geht.
-- Ärger --
Ich habe mich schon ein paar mal mit Variant versucht. Und mit den neuen Funktionen VariantPut und VariantGet kann man einiges von dem was mit ANY, AUF DI, AR2 und AWL geht auch in SCL, FUP und KOP bei Optimierten machen.
Das ist manchmal schneller als mit AR2, wenn die Strukturen klein sind und manchmal langsamer, wenn die Strukturen groß sind.
Jetzt kommt es drauf an wieviel des Programms mit diesen seltsamen Zeigern arbeitet.
Ein Variant an der Schnittstelle ist eine Referenz, an kann ihn versorgen womit immer man will. D.h. da wird nix kopiert. Das ist schnell. Die beiden Variant-Funktionen kopieren die Daten aber dann doch in eine lokale Variable, die genau den Typen haben muss, mit dem man 4 Aufrufe drüber den Variant versorgt hat. :-(
Bei dem einen Altprogramm aus Step7 V5 Zeiten das ich hatte, konnte ich die Kopieraktion an vier Stellen bündeln. D.h. 99% des Programms arbeiten mit der Kopie und 1% arbeitet mit den Orginaldaten in verschiedenen DB. Das Programm läuft jetzt auf einer 1516. Es hat in der migrierten AWL-ANY-Version 136ms Zykluszeit. In der nachgearbeiteten SCL-FUP-Variant-Version hat es eine Zykluszeit von 44ms. Aus der 319 hatte es eien Zykluszeit von ein bischen über 200ms.
Bei einem anderen Altprogramm werden auf einer großen Struktur in den verschiedensten Bausteine Zugriffe gemacht. AWL-ANY benötigt zwischen 85 und 95ms. Die nachgearbeitet Version hat 24 VariantGet und 6 VariantPut und braucht 140ms. Mist.
Dann gibt es noch einen Trick, der aber auch nicht wirklich weit kommt. Es gibt sogenannte ArrayDB. Das sind DB, die aus einem Array of UDT bestehen. Auf diese kann man mit ReadFromArrayDB und WriteToArrayDB zugreifen. Der DB wird mittels eines Inputs von Typ ANY_DB ausgewählt und dann gibt man noch einen index für den Zugriff auf das Array mit.
Um genau das zu bekommen, was Jochen machen will kann man nun folgendes machen. Man erzeugt sich viele ArrayDB of myUDT. Wobei aber immer nur ein Element im Array ist. Dann macht man sich in einem DB ein Array of ANY_DB. Und in einem anderen DB egt man sich einen myUDT an. Dann kann man in einer Funktion mittels Index aus dem Array den DB auswählen und erhält mittel ReadFromArrayDB( db := ArrayOfANY_DB[ index ], index := 0, dest => "Arbeitskopie".myUDTvar ) eine Kopie des Inhalt aus dem Array DB. Die Gegenrichtung klappt ganz ähnlich. Es ist auch nicht nötig myUDTvar in einem andern Db zu haben, geht auch in der Temp.
Alles in allem ein rechter Krampf, aber jetzt hat man eine Multiplexer der optimierten Inhalt über die DB-Nummer, denn nichts andres ist im ANY_DB, auswählt.
Nachteil 1: Jeder ANY_DB hat einen Overhead von 48 Byte. Für kleine Strukturen ist eine Struktur pro ArrayDB sehr unwirtschaftlich. Aber man kann ja dann 100 davon reinlegen.
Nachteil 2: Die Funktionen kopieren die Daten, d.h. für große Strukturen wird es wieder unwirtschaftlich.
Nachteil 3: Wie bekommt man die DB-Namen in das Array of DB_ANY. Bisher klappt das nur über die DB-Nummer ... Was soll das?
Es ist zum aus der Haut fahren. Man erkennt die Ansätze, aber irgenwie ist das alles unfertig. Es fehlen die Möglichkeit einen Variant im DB zu speichern und auf den Variant ohne eine Kopie zuzugreifen.
Was die 1516 allerdings deutlich schneller kann als die 319 ist der Zugriff auf viele DB. Eines meiner migrierten Programme greift in einem FC auf viele DB zu, 36 DB werden verwendet. Der Baustein besteht im wesentlichen aus AUF DBa, L b, AUF DBc, T d. Zykluszeit auf der 319 33 ms. Davon die Hälfte in dieser unsäglichen Kopierorgie. Das bekommt man raus, wenn man mal den einen Call per M-Bit überspringt. Da läuft das Programm zwar nicht mehr richtig, aber der Rest verbrät immernoh die gleiche Zeit. Zykluszeit auf der 1516 16 ms, das Kopieren verbraucht irgendwie nur 1ms oder sogar weniger.
'n schön' Tach auch
HB