Jump to content

Optimized Array.au3


-Ultima-
 Share

Recommended Posts

I don't see the default column width any differently than I see the default window size. As long as the initial window size gives a good preview, the rest can be handled by either resizing (the window) or scrolling the scrollbar.

If the user has to scroll to see all of the data, we (obviously) wouldn't resize the window to try and prevent the need to scroll. In such cases, trying to let the user see things at first glace without changing something in the listview would (IMO) be a wasted effort, since scrolling would be unavoidable. Scrolling a listview takes just about the same amount of effort as resizing a column. Also, if the user happens to have a first column full of long sentences, phrases, or whatnot -- long enough to force a horizontal scroll -- and we automatically resize the column to fit all of that text, then we're back to square one; the user won't be able to see all of the text without manipulating the listview in some way or another.

Hi,

Strange, I get no "forced scrolling", no matter how long I have tried [how long are you talking about!]; what makes you say that?

Otherwise, I would agree with you!

Best, randall

Link to comment
Share on other sites

  • Replies 137
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

#include "array.au3"
local $a[1] = ["The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."]
_arraydisplay($a)

(After inserting the 3 lines you recommended to be added in post 93 into my last attachment, that is)

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

#include "array.au3"
local $a[1] = ["The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."]
_arraydisplay($a)

(After inserting the 3 lines you recommended to be added in post 93 into my last attachment, that is)

Hi,

OK, strange! It doesn't happen in my version.

Oh well... when I run your version, sometimes (at least!) 1D displays automatically widened too!; is that what you find?

Best , Randall

Link to comment
Share on other sites

  • 2 weeks later...

I tested Ultima's arraydisplay function and I have these suggestions:

1) change default $sReplace = "~" to $sReplace = "|" so if we call _ArrayDisplay function without any parametres then we want to see unchanged content of array. Here can be also little speed optimization: If $sReplace is equal to $sSeparator then don't do StringReplace()

here is example:

Hi,

I have looked at this;

1. Easy to change the default if Ultima agrees;

_ArrayDisplayEx(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "|", $sReplace = "|")oÝ÷ Ûr)­çÞ®Ú,¥çz÷«ÊØbòÛN4jk¢ø§«%j¸¯}ÖyƧ©Úëazmè~Ø^­êeiǦz{lz«j×¥ÊÚ,µªíÂ+ajÈ­q©î²æ¥&Þo*Z²Çºy^²Ê^¢^ç¶Þ¦Vzz-²+ØjV¬Â§!ø«²Ü+¢×¢µ«ºÚ¶ëvÚ­«!-Xº'{¦mêè}Ê%ºiìjëh×6Func _ArrayDisplayBr(Const ByRef $avArrayF, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "|", $sReplace = "|")
    If Not IsArray($avArrayF) Then Return SetError(1, 0, 0)
    Local $iDimension = UBound($avArrayF, 0), $iUBound = UBound($avArrayF, 1) - 1, $iSubMax = UBound($avArrayF, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)
    Local $timer = TimerInit()
    Local $timerprep = TimerInit()
    If $sSeparator <> $sReplace Then
        If $iDimension = 2 Then
            Local $avArray[$iUBound + 1][$iSubMax + 1]
            For $i = 0 To $iUBound
                For $j = 0 To $iSubMax
                    $avArray[$i][$j] = StringReplace($avArrayF[$i][$j], $sSeparator, $sReplace, 0, 1)
                Next
            Next
        ElseIf $iDimension = 1 Then
            Local $avArray[$iUBound + 1]
            For $i = 0 To $iUBound
                $avArray[$i] = StringReplace($avArrayF[$i], $sSeparator, $sReplace, 0, 1)
            Next
        EndIf
    Else
        $avArray = $avArrayF
;~      $avArray[0] = $avArrayF[0]
    EndIf

    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)oÝ÷ Ûáz|q©ì¥çºazf§j§¶Þ¯4Ñ«­¢+Ø%½ÈÀÌØí¤ô ÀÌØí¥1Y%UQ¡ÉÍ¡½±¬Ä¤Q¼ÀÌØí¥U  ½Õ¹($%±±MÑÉÕÑMÑÑ ÀÌØíÑ  ÕÈ°ÅÕ½ÐíQáÐÅÕ½Ðì°ÅÕ½ÐílÅÕ½ÐìµÀìÀÌØí¤µÀìÅÕ½ÐítÅÕ½Ðì¤(($$ì±¥ÍÑ٥ܥѴ($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí%Ñ´ÅÕ½Ðì°ÀÌØí¤¤($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½ÐíMÕ%Ñ´ÅÕ½Ðì°À¤($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí5ͬÅÕ½Ðì°ÀÌØí¥5ͬ¤($%U%
ÑɱM¹5Í ÀÌØí¡1¥ÍÑY¥Ü°ÀÌØí}IIe
=9MQ9Q}1Y5}%9MIQ%Q5°À°ÀÌØíÁ%Ñ´¤(($$ìMб¥ÍÑÙ¥ÜÍեѴÑáÐ($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí5ͬÅÕ½Ðì°ÀÌØí}IIe
=9MQ9Q}1Y%}QaP¤($%½ÈÀÌØí¨ôÈ´ÀÌØí¥¥µ¹Í¥½¸Q¼ÀÌØí¥9Õµ%ѵ̴ÀÌØí¥¥µ¹Í¥½¸($$%MÝ¥Ñ ÀÌØí¥ÉÉåQåÁìÀÌØí¥¥µ¹Í¥½¸¬È¨ÀÌØí¥QɹÍÁ½Í´Ä($$$%
ÍÀìÅ($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÄìÉ($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí¥ulÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÈìÅP($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÌìÉP($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí©ulÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$%¹MÝ¥Ñ ($$%%MÑÉ¥¹1¸ ÀÌØíÍQáФÐìÀÌØí¥    ÕÈQ¡¸($$$$ÀÌØí¥    ÕÈôMÑÉ¥¹1¸ ÀÌØíÍQáФ($$$%1½°ÀÌØíÑ    ÕÈô±±MÑÉÕÑ
ÉÑ ÅÕ½Ðí¡ÈQáÑlÅÕ½ÐìµÀìÀÌØí¥ ÕȵÀìÅÕ½ÐítÅÕ½Ð줰ÀÌØíÁ   ÕÈô±±MÑÉÕÑÑAÑÈ ÀÌØíÑ   ÕȤ($$$%1½°ÀÌØíÑ%Ñ´ô±±MÑÉÕÑ
ÉÑ ÀÌØí}IIe
=9MQ9Q}Ñ1Y%Q4¤°ÀÌØíÁ%Ñ´ô±±MÑÉÕÑÑAÑÈ ÀÌØíÑ%Ñ´¤($$$%
½¹Í½±]É¥Ñ ÅÕ½ÐíAI= 14¸¸¸¸¸¸¸¸¸¸¸¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ÅÕ½ÐìµÀì1¤($$%¹%($$%±±MÑÉÕÑMÑÑ ÀÌØíÑ   ÕÈ°ÅÕ½ÐíQáÐÅÕ½Ðì°ÀÌØíÍQáФ($$%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½ÐíMÕ%Ñ´ÅÕ½Ðì°ÀÌØí¨´Ä¬ÀÌØí¥¥µ¹Í¥½¸¤($$%U%
ÑɱM¹5Í ÀÌØí¡1¥ÍÑY¥Ü°ÀÌØí}IIe
=9MQ9Q}1Y5}MQ%Q5°À°ÀÌØíÁ%Ñ´¤($%9áÐ(%9á

This still seems easy to raed and easy to maintain?; over to Ultima?

best, randall

(full udf attached)

Link to comment
Share on other sites

No can do; the speed boost comes at a price. Try displaying the array Zedna posted:

Dim $avArray[8]
$avArray[0] = 7
$avArray[1] = "Brian|Smith"
$avArray[2] = "Jon|Brown"
$avArray[3] = "Larry|Maddison"
$avArray[4] = "Christa|Heinrich"
$avArray[5] = "Rick|Richards"
$avArray[6] = "Jack|Tomas"
$avArray[7] = "Gregory|Thompson"

The array does not display properly because you're setting GUIDataSeparatorChar to "|", then replacing "|" with "|" (not doing anything :)). Really, the replacement should actually never be set identical to the separator, but I got too lazy to check for that. Maybe some error should be spit back if they are set to be the same...

At any rate, I think the best solution would be to use different separators, and make the on-the-fly replacement character a non-printable character (since if you want to display an array, it should not be containing non-printable characters in the first place). That'll make sure the user sees the array with its contents unchanged (and that's how it's currently implemented).

I had once considered using Execute(), but decided not to because there were alternatives. For the most part, the only time I use Execute() is if it really is the only way I could perform something. Too, using Execute() doesn't bring any speed advantages (even though the loop was tightened to have less if statements; Execute has its own set of overheads as well that you need to worry about).

Regarding the 4th suggestion... IMHO, I think that makes the code less readable. For what reason are you generating the whole text-representation of the array if you're not going to use it throughout?

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

Try displaying the array Zedna posted:

Dim $avArray[8]
$avArray[0] = 7
$avArray[1] = "Brian|Smith"
$avArray[2] = "Jon|Brown"
$avArray[3] = "Larry|Maddison"
$avArray[4] = "Christa|Heinrich"
$avArray[5] = "Rick|Richards"
$avArray[6] = "Jack|Tomas"
$avArray[7] = "Gregory|Thompson"
Hi,

Thanks for your reply.

1. That was actually first posted by me as an example of my proposal that the default allow 1D arrays of delimited strings to be displayed as 2D;

Displays 1D arrays with delimiters , as though 2D

2. It does display correctly if you give appropriate parameters, changing the ArrayDisplay delimiter; just not consistent with Zedna's idea of that being the default. The default, I think, should be whichever is the fastest for most people.. but you and i always seem to disagree!

_ArrayDisplayBr ($avArray, "_ArrayDisplayE() Test[1D,  not transposed]",0,0,"~")
_ArrayDisplay($avArray, "_ArrayDisplay() Test[1D,  not transposed]",0,0,"~")oÝ÷ ÚÚºÚ"µÍÐ^QÜ^P
    ÌÍØ]^K   ][Ý×Ð^QÜ^QJ
HÝÌQÝ[ÜÜÙYI][ÝË ][Ýß][ÝË    ][Ýß  ][ÝÊBÐ^QÜ^J ÌÍØ]^K   ][Ý×Ð^QÜ^J
HÝÌQÝ[ÜÜÙYK   ÌÎNßÌÎNÉ][ÝË    ][Ýß][ÝË    ][Ýß  ][ÝÊ

No can do; the speed boost comes at a price.

No price to me! again, we disagree.

That'll make sure the user sees the array with its contents unchanged (and that's how it's currently implemented).

Not in 3.2.10.0, as I tested ti; still not default and needs the changed parameters to display properly.

At any rate, I think the best solution would be to use different separators, and make the on-the-fly replacement character a non-printable character (since if you want to display an array, it should not be containing non-printable characters in the first place).

Not consistent with my needs, so I disagree again! surprise; also don't understand...

using Execute() doesn't bring any speed advantages (even though the loop was tightened to have less if statements

I presume you mean "except here" as it is obviously faster!

Regarding the 4th suggestion... IMHO, I think that makes the code less readable. For what reason are you generating the whole text-representation of the array if you're not going to use it throughout?

That is the point; I am -not- generating past 4000; and getting rid of stringsplit from the sub-loop and using Switch/ case instead seems to have sped it up considerably..

Best, Randall

Edited by randallc
Link to comment
Share on other sites

are you just interested in spedd, not crashing or display?

I'm not so interested in speed that would sacrifice stability for it.

You previously criticized me about seemingly putting speed at a higher priority than display and stability (but you're now guilty of it). I gave you my response, and that's how I'm sticking to it. I still disagree that there should be a display error by default just because the user is using the default GUIDataSeparatorChar in their array. Why should the user have to change the contents of their array to view it? I'm agreeing with Zedna here; when the user wants to display the array, it should be displayed as they expect it to by default. In fact, the function shouldn't even allow the display problem to happen at all -- the function should never be displaying incorrect/partial data.

It may not look like a sacrifice to you, but you're not the only _ArrayDisplay user. When I said "that's how it's currently implemented," I was referring to how it's currently implemented in the last attachment I posted.

I am -not- generating past 4000

Whether or not you're generating over 4000 listview items has nothing to do with code readability/maintainability. In the end, by splitting the text manipulation to 3 different places in the code, one has to jump from place to place to find how/why text is the way it is.

Anyhow, test the attachment.

_ArrayDisplayBr() is what you last posted

_ArrayDisplayCurr() is what I last posted, except with one difference -- it checks the buffer size in the outer loop instead of inner

_ArrayDisplayWithExecute() is what I last, except with your 2nd suggestion (to use Execute)

The speed increase by making the code more mangled is 5% -- not worth it, IMO. As for using Execute, you'll see that it's ~6% slower than _ArrayDisplayCurr(). The only reason your Execute() code looked faster was because (1) it was skipping out on StringReplace, and (2) it was doing less comparisons to find a buffer size large enough to fit every piece of text in.

Skipping out on StringReplace() messes up the display. Comparing the buffer size in the outer loop... well, that grossly overestimates the buffer size.

I could just as easily gain 8% performance back with somewhat higher maintainability than your code by splitting into multiple loops with several if statements or switches, as I originally had it before my last few attachments, but again, that makes it less maintainable.

test.au3

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

Hi,

I couldn't post my own topic for some reason to do with permissions. This seemed like the next best place to put my contribution.

It's just two functions I wrote to make working with arrays easier. I'm not implying that they should be put into any array UDF's (but you are most welcome to if deemed appropriate.)

These two functions were written for working with arrays that will have an undetermined number of elements. Using these functions a lot of declaration and "range exceeded" errors can be avoided as array boundaries become more irrelevant and more easily manipulated.

Enjoy!

;===============================================================================
;
; Function Name:  _ArrayInsertElement
; Description:  Inserts a value into an array at a given element key.  Even if
;                that key is beyond the range of the declared variable.
;
;                Will append the value to the array if no key given.
;
;===============================================================================

Func _ArrayInsertElement(ByRef $array, $elementValue = '', $elementKey = -1)
    If IsArray($array) Then
        If $elementKey = -1 Then
            $elementKey = UBound($array)
        EndIf
        _ArrayExtendRange($array, $elementKey)
        $array[$elementKey] = $elementValue
        SetError(0)
        Return 1
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc  ;==>_ArrayInsertElement


;===============================================================================
;
; Function Name:  _ArrayExtendRange
; Description:  Extends the range of an array while retaining existing values.
;                Does not work with multi-dimensional arrays.
;                Remember: Asking for example, 30 will bring your array index
;                          to 30 but the total number of elements to 31 because
;                          $array[0] must be counted.
;
;===============================================================================

Func _ArrayExtendRange(ByRef $array, $numberElement = 0)
    If IsArray($array) Then
        $arrayExistingRange = UBound($array) - 1
        If $arrayExistingRange < $numberElement Then
            ReDim $array[$numberElement + 1]
            SetError(0)
            Return 1
        Else
            SetError(0)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc  ;==>_ArrayExtendRange

Example usage:

(This is very simple, but think loops with variable amounts of data being placed into an array)

#include <Array.au3>

Dim $hashes[1]
_ArrayInsertElement($hashes, '10fa4b6dc11ac66abf67f0e4f64a65a4', 0)
_ArrayInsertElement($hashes, 'a9e40e2af0296318f127f6fc7990ea46', 15)
_ArrayInsertElement($hashes, 'e6c2b07bb051c361696dff1cad92b8d1')
_ArrayInsertElement($hashes, 'd4b2c35b8d817fc737014916e6170d64')
_ArrayDisplay($hashes)
Link to comment
Share on other sites

I'm agreeing with Zedna here; when the user wants to display the array, it should be displayed as they expect it to by default.

Hi,

Thanks again for your interest; I may learn something, and I only "argue" in the hope of both learning and provoking (hopefully) beneficial debate and possible optimization. (criticcism not intended)

1. On balance, despite my requirements, I believe you and Zedna have convinced me, now that I see he was using my example script with a different aim! - So I agree with

- Default showing exact arrays

- Execute being slow if you are prepared to adjust everything else to expand despite readability.

- but;

2. You have the script speed wrong; the "fair" comparison is

_arraydisplaybr($a, "", -1, 0, chr(1), chr(1)) ; only way to make comparison fair -- by making it display text properlyoÝ÷ Ù«-+Êek+-ë^Æ×(®·¶­¢®¢×¶ç{ë8óyÓ]ú×muçyïÎ÷õ*çH¦¦º/zg§¶ò¢êìr¸©¶Ê^yاʫ£  ìr¸©·ú®¢×·"²Ëhëm«Z²«¨µ×jémªê-ç²Ê&z)©®â±«b¢vî¶+fk&ÞÂí+OJ'ðzwu©è¶«¥ªÚë^¯jyzÚrL­Û¢jZµ¦â+ro'!jx"
®¢Ôëj{)¢Çªºij¶¦z׫¶®¢Ú)*'²«¨¶«jg­­©Ýi×b
5۵Ƨv­¶)àn+ZÖ¬{(ê-êߺw,à¦lº·¢}©Z®¹÷Þ®+¦ºé¢~Ø^²v+,¢k
Þj׫nëHjh Úا¶¬j·#
.ÖÞ{^­ë-yÛh櫬µ§u©e= %¶.­Éè¶È 'âq©í¶azÊ^yÔáz·¢±¦î)íæî}÷«r©òÁ¬¬¢wvÊÞ¸­xÛaȬ¥êájzÛ^­ú+­æi¸¥Ü­¢èrwuç[+{4ÒØ^«­¢+Ø%½ÈÀÌØí¤ôÀQ¼ÀÌØí¥1Y%UQ¡ÉÍ¡½±ìÀÌØí¥U    ½Õ¹($$ÀÌØíÙÉÉåQáÑlÀÌØí¥tôÅÕ½ÐílÅÕ½ÐìµÀìÀÌØí¤µÀìÅÕ½ÐítÅÕ½Ðì($%MÝ¥Ñ ÀÌØí¥ÉÉåQåÁìÀÌØí¥¥µ¹Í¥½¸¬È¨ÀÌØí¥QɹÍÁ½Í´Ä($$%
ÍÀìÅ($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉälÀÌØí¥MÕ5át($$$$$ÀÌØíÙÉÉåQáÑlÀÌØí¥tµÀìôÀÌØíÍMÁÉѽȵÀìÀÌØíÙÉÉålÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$$%9áÐ($$%
ÍÄìÉ($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙÉÉåQáÑlÀÌØí¥tµÀìôÀÌØíÍMÁÉѽȵÀìÀÌØíÙÉÉålÀÌØí¥ulÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%9áÐ($$%
ÍÈìÅP($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙÉÉåQáÑlÀÌØí¥tµÀìôÀÌØíÍMÁÉѽȵÀìÀÌØíÙÉÉålÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%9áÐ($$%
ÍÌìÉP($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙÉÉåQáÑlÀÌØí¥tµÀìôÀÌØíÍMÁÉѽȵÀìÀÌØíÙÉÉålÀÌØí©ulÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$$%9áÐ($%¹MÝ¥Ñ (($$ìMеàÕÈÍ¥é(%9áÐ(%½ÈÀÌØí¤ô ÀÌØí¥1Y%UQ¡ÉÍ¡½±¬Ä¤Q¼ÀÌØí¥U ½Õ¹´Ä($%MÝ¥Ñ ÀÌØí¥ÉÉåQåÁìÀÌØí¥¥µ¹Í¥½¸¬È¨ÀÌØí¥QɹÍÁ½Í´Ä($$%
ÍÀìÅ($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉälÀÌØí¥MÕ5át($$$$$ÀÌØíÙQµÀôMÑÉ¥¹1¸ ÀÌØíÙÉÉålÀÌØí¥t¤($$$$%%ÀÌØíÙQµÀÐìÀÌØí¥    ÕÈQ¡¸ÀÌØí¥ ÕÈôÀÌØíÙQµÀ($$$%9áÐ($$%
ÍÄìÉ($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙQµÀôMÑÉ¥¹1¸ ÀÌØíÙÉÉålÀÌØí¥ulÀÌØí©t¤($$$$%%ÀÌØíÙQµÀÐìÀÌØí¥  ÕÈQ¡¸ÀÌØí¥ ÕÈôÀÌØíÙQµÀ($$$%9áÐ($$%
ÍÈìÅP($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙQµÀôMÑÉ¥¹1¸ ÀÌØíÙÉÉålÀÌØí©t¤($$$$%%ÀÌØíÙQµÀÐìÀÌØí¥ ÕÈQ¡¸ÀÌØí¥ ÕÈôÀÌØíÙQµÀ($$$%9áÐ($$%
ÍÌìÉP($$$%½ÈÀÌØí¨ôÀQ¼ÀÌØí¥MÕ5àìѼÑáÐÉÉä($$$$$ÀÌØíÙQµÀôMÑÉ¥¹1¸ ÀÌØíÙÉÉålÀÌØí©ulÀÌØí¥t¤($$$$%%ÀÌØíÙQµÀÐìÀÌØí¥ ÕÈQ¡¸ÀÌØí¥ ÕÈôÀÌØíÙQµÀ($$$%9áÐ($%¹MÝ¥Ñ (%9áÐ($ÀÌØí¥ ÕȬôoÝ÷ Ù8^«­¢+Ø%½ÈÀÌØí¤ô ÀÌØí¥1Y%UQ¡ÉÍ¡½±¬Ä¤Q¼ÀÌØí¥U    ½Õ¹($%±±MÑÉÕÑMÑÑ ÀÌØíÑ  ÕÈ°ÅÕ½ÐíQáÐÅÕ½Ðì°ÅÕ½ÐílÅÕ½ÐìµÀìÀÌØí¤µÀìÅÕ½ÐítÅÕ½Ðì¤(($$ì±¥ÍÑ٥ܥѴ($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí%Ñ´ÅÕ½Ðì°ÀÌØí¤¤($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½ÐíMÕ%Ñ´ÅÕ½Ðì°À¤($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí5ͬÅÕ½Ðì°ÀÌØí¥5ͬ¤($%U%
ÑɱM¹5Í ÀÌØí¡1¥ÍÑY¥Ü°ÀÌØí}IIe
=9MQ9Q}1Y5}%9MIQ%Q5°À°ÀÌØíÁ%Ñ´¤(($$ìMб¥ÍÑÙ¥ÜÍեѴÑáÐ($%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½Ðí5ͬÅÕ½Ðì°ÀÌØí}IIe
=9MQ9Q}1Y%}QaP¤($%½ÈÀÌØí¨ôÈ´ÀÌØí¥¥µ¹Í¥½¸Q¼ÀÌØí¥9Õµ%ѵ̴ÀÌØí¥¥µ¹Í¥½¸($$%MÝ¥Ñ ÀÌØí¥ÉÉåQåÁìÀÌØí¥¥µ¹Í¥½¸¬È¨ÀÌØí¥QɹÍÁ½Í´Ä($$$%
ÍÀìÅ($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÄìÉ($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí¥ulÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÈìÅP($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí©tìÀÌØíÍMÁÉѽȵÀì($$$%
ÍÌìÉP($$$$$ÀÌØíÍQáÐôÀÌØíÙÉÉålÀÌØí©ulÀÌØí¥tìÀÌØíÍMÁÉѽȵÀì($$%¹MÝ¥Ñ ($$%±±MÑÉÕÑMÑÑ ÀÌØíÑ    ÕÈ°ÅÕ½ÐíQáÐÅÕ½Ðì°ÀÌØíÍQáФ($$%±±MÑÉÕÑMÑÑ ÀÌØíÑ%Ñ´°ÅÕ½ÐíMÕ%Ñ´ÅÕ½Ðì°ÀÌØí¨´Ä¬ÀÌØí¥¥µ¹Í¥½¸¤($$%U%
ÑɱM¹5Í ÀÌØí¡1¥ÍÑY¥Ü°ÀÌØí}IIe
=9MQ9Q}1Y5}MQ%Q5°À°ÀÌØíÁ%Ñ´¤($%9áÐ(%9á
Edited by randallc
Link to comment
Share on other sites

You have the script speed wrong; the "fair" comparison is

_arraydisplaybr($a, "", -1, 0, chr(1), chr(1)); only way to make comparison fair -- by making it display text properly
No, that's still not a fair comparison. A fair comparison happens only when the output from both things being compared are as close as possible. Again, using the same character for replacement as GUIDataSeparatorChar will cause an improper display; columns will get shifted over for any row that contains the replacement character. Although chr(1) is a non-printable character, when other columns get pushed over, the user might think something is in a particular column when in fact it isn't; in fact, it was part of the previous column, but because the replacement "failed," one cell got treated as multiple. Again, this will happen any time $sSeparator is identical to $sReplace, and the array contains data with $sSeparator. If something has a failure case, and there is a way around it, then to me, it doesn't matter if the one that fails is faster; it's not the solution I would pick for a standard UDF implementation.

If you know for sure that your array isn't going to contain $sSeparator/$sReplace, then by all means, use your method; I'll agree that it is faster. But since it's a general UDF, we can't anticipate what data is going to be displayed, so we can't just assume users won't run into the problem. We can only attempt to mitigate it as best as we can, and choosing sensible defaults is the best step towards that goal. I'm still wondering if I should display some kind of warning when $sSeparator == $sReplace, or if I should even allow it continue in the first place.

By the way, when you're measuring speed difference, you should be doing ((new time) - (original time))/(original time). In your test, it would be (2.555765048 - 3.950136121)/3.950136121 = -0.353, or 35.5% less time.

Regarding adding options... I suppose we could change way $iTranspose is handled, but I'm not really sure what else needs to be added to this function (keep in mind that it should really be kept simple, and not attempt to incorporate the kitchen sink and coffee maker). As it stands, _ArrayDisplay() seems (to me) to be almost as full featured as it needs to be.

Regarding the large buffer size, it's not as big a deal as I make out to sound (though it can still be one); the problem is that _ArrayDisplay() might waste a lot more memory than is necessary. This probably won't be an issue in most cases, but believe me, I've tested LARGE arrays before, and AutoIt ended up complaining that my system (which has 2GB) was out of RAM (and the AutoIt process really was using almost 2GB of RAM). By setting TextMax to a smaller number, I might potentially be able to display larger arrays, so I would rather take that with the performance hit rather than having it fail entirely. Even with how I currently have it initialized to 64 and comparing in the inner loop, I'm still overestimating the buffer size, since each listview sub-item can actually be smaller than the maximum length I detected, but it's much lower than the major overestimation that StringLen($avArrayText[$i]) would potentially cause :D Note how I keep saying "might" in this paragraph, as it may well be the case that I am wrong about the TextMax affecting the memory usage, but it's not something I've tested too thoroughly. If it turns out that I'm wrong (and I'm beginning to suspect that I am, after re-reading MSDN), then I'll gladly move the buffer size detection into the outer loop without hesitation.

[ Edit: So yeah, after some simple tests, it doesn't appear to me that AutoIt is using the buffer size for each and every listview sub-item. Moving the buffer size checking to the outer loop indeed does look like it'll be a nice optimization, with the only drawback being that it uses (very slightly) more memory, since $tBuffer will be slightly larger. ]

What bug are you referring to with regards to the buffer check? I see nothing wrong with it. It's very much readable as is (it's just 2 lines that are very clear), and it's much more maintainable, since it's only those 2 lines that check the buffer size rather than copying over for each case.

Edit: _ArrayDisplay() as I currently have it (only difference since the last candidate attachment for UDF being that buffer size checking was moved to outer loop)

Func _ArrayDisplay(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|")
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)

    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)

    ; Separator handling
    If $sSeparator = "" Then $sSeparator = Chr(1)

    ; Declare variables
    Local $i, $j, $vTmp, $aItem, $avArrayText, $sHeader = "Row", $iBuffer = 2048000
    Local $iColLimit = 200, $iLVIAddUDFThreshold = 4000, $iWidth = 640, $iHeight = 480
    Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)

    ; Swap dimensions if transposing
    If $iSubMax < 0 Then $iSubMax = 0
    If $iTranspose Then
        $vTmp = $iUBound
        $iUBound = $iSubMax
        $iSubMax = $vTmp
    EndIf

    ; Set limits for dimensions
    If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
    If $iItemLimit = 1 Then $iItemLimit = $iLVIAddUDFThreshold
    If $iItemLimit < 1 Then $iItemLimit = $iUBound
    If $iUBound > $iItemLimit Then $iUBound = $iItemLimit
    If $iLVIAddUDFThreshold > $iUBound Then $iLVIAddUDFThreshold = $iUBound

    ; Set header up
    For $i = 0 To $iSubMax
        $sHeader &= $sSeparator & "[" & $i & "]"
    Next

    ; Convert array into text for listview
    Local $avArrayText[$iUBound + 1]
    For $i = 0 To $iUBound
        $avArrayText[$i] = "[" & $i & "]"
        For $j = 0 To $iSubMax
            ; Get current item
            If $iDimension = 1 Then
                If $iTranspose Then
                    $vTmp = $avArray[$j]
                Else
                    $vTmp = $avArray[$i]
                EndIf
            Else
                If $iTranspose Then
                    $vTmp = $avArray[$j][$i]
                Else
                    $vTmp = $avArray[$i][$j]
                EndIf
            EndIf

            ; Add to text array
            $avArrayText[$i] &= $sSeparator & StringReplace($vTmp, $sSeparator, $sReplace, 0, 1)
        Next

        ; Set max buffer size
        $vTmp = StringLen($avArrayText[$i])
        If $vTmp > $iBuffer Then $iBuffer = $vTmp
    Next
    $iBuffer += 1

    ; GUI Constants
    Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66
    Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40
    Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200
    Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2
    Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4
    Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
    Local Const $_ARRAYCONSTANT_LVIF_PARAM = 0x4
    Local Const $_ARRAYCONSTANT_LVIF_TEXT = 0x1
    Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
    Local Const $_ARRAYCONSTANT_LVM_INSERTITEMA = (0x1000 + 7)
    Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
    Local Const $_ARRAYCONSTANT_LVM_SETITEMA = (0x1000 + 6)
    Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
    Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
    Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
    Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
    Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
    Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
    Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000
    Local Const $_ARRAYCONSTANT_tagLVITEM = "int Mask;int Item;int SubItem;int State;int StateMask;ptr Text;int TextMax;int Image;int Param;int Indent;int GroupID;int Columns;ptr pColumns"

    Local $iAddMask = BitOR($_ARRAYCONSTANT_LVIF_TEXT, $_ARRAYCONSTANT_LVIF_PARAM)
    Local $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]"), $pBuffer = DllStructGetPtr($tBuffer)
    Local $tItem = DllStructCreate($_ARRAYCONSTANT_tagLVITEM), $pItem = DllStructGetPtr($tItem)
    DllStructSetData($tItem, "Param", 0)
    DllStructSetData($tItem, "Text", $pBuffer)
    DllStructSetData($tItem, "TextMax", $iBuffer)

    ; Set interface up
    Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
    Local $aiGUISize = WinGetClientSize($hGUI)
    Local $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
    Local $hCopy = GUICtrlCreateButton("Copy Selected", 3, $aiGUISize[1] - 23, $aiGUISize[0] - 6, 20)

    GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
    GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)

    ; Fill listview
    For $i = 0 To $iLVIAddUDFThreshold
        GUICtrlCreateListViewItem($avArrayText[$i], $hListView)
    Next
    For $i = ($iLVIAddUDFThreshold + 1) To $iUBound
        $aItem = StringSplit($avArrayText[$i], $sSeparator)
        DllStructSetData($tBuffer, "Text", $aItem[1])

        ; Add listview item
        DllStructSetData($tItem, "Item", $i)
        DllStructSetData($tItem, "SubItem", 0)
        DllStructSetData($tItem, "Mask", $iAddMask)
        GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_INSERTITEMA, 0, $pItem)

        ; Set listview subitem text
        DllStructSetData($tItem, "Mask", $_ARRAYCONSTANT_LVIF_TEXT)
        For $j = 2 To $aItem[0]
            DllStructSetData($tBuffer, "Text", $aItem[$j])
            DllStructSetData($tItem, "SubItem", $j-1)
            GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETITEMA, 0, $pItem)
        Next
    Next

    ; Show dialog
    GUISetState(@SW_SHOW, $hGUI)
    While 1
        Switch GUIGetMsg()
            Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
                ExitLoop

            Case $hCopy
                Local $sClip = ""

                ; Get selected indices [ _GUICtrlListView_GetSelectedIndices($hListView, True) ]
                Local $aiCurItems[1] = [0]
                For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
                    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then
                        $aiCurItems[0] += 1
                        ReDim $aiCurItems[$aiCurItems[0] + 1]
                        $aiCurItems[$aiCurItems[0]] = $i
                    EndIf
                Next

                ; Generate clipboard text
                If Not $aiCurItems[0] Then
                    For $sItem In $avArrayText
                        $sClip &= $sItem & @CRLF
                    Next
                Else
                    For $i = 1 To UBound($aiCurItems) - 1
                        $sClip &= $avArrayText[$aiCurItems[$i]] & @CRLF
                    Next
                EndIf
                ClipPut($sClip)
        EndSwitch
    WEnd
    GUIDelete($hGUI)

    Opt("GUIOnEventMode", $iOnEventMode)
    Opt("GUIDataSeparatorChar", $sDataSeparatorChar)

    Return 1
EndFunc   ;==>_ArrayDisplay
Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

What bug are you referring to with regards to the buffer check?

Hi,

I take your points; i was referring to my udf "ArrayDisplayBr"

In your test, it would be (2.555765048 - 3.950136121)/3.950136121 = -0.353, or 35.5% less time.

True, but if it were 2secs, 4 secs, you would agree that you would say "50% less time", and my ratio would say "twice as fast" or "speed ratio is 200%" ;as long as we know what we mean?

;=================

I agree about the chr(1); I will keep my udf with the speed option, and some people might want that; anyway; up to you about whether the standard include has such an option.

Same goes for th option of displaying 1D delimited arrays as 2D.

;=================

Best, randall

Link to comment
Share on other sites

If StringLen($sTxt) > $iBuffer Then
                $iBuffer = StringLen($sTxt)
                Local $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]"), $pBuffer = DllStructGetPtr($tBuffer)
                Local $tItem = DllStructCreate($_ARRAYCONSTANT_tagLVITEM), $pItem = DllStructGetPtr($tItem)
                ConsoleWrite("PROBLEM...........*********************************" & @LF)
            EndIf

I presume this is the piece of code you're referring to? If so, can you provide an example where it does run into this condition? The point behind detecting $iBuffer while $avArrayText was getting generated was to check to make sure the buffer size would be large enough to fit any item in the array. It's unnecessary work to check again while the listview is getting filled.

About the speed difference... Yeah, I know what you meant. I guess that was just the "take speed improvements seriously, so measure/calculate them carefully" side of me kicking in :D

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

If so, can you provide an example where it does run into this condition?

Hi,

do you realise,again, that was only in my UDF? I did make such an array, where I had an element with 255 chars, and before that, in the first 4000, each element only had 2 chars ; but I was only checking the buffer at the end of the first 4000, and the large one was not in that check...

I can give an array and the udf that produces it if you wish (the solution as you quote did not work to reset the buffer size); but you are not going to run into that in your current udf, so I presume you don't need it?

Best, Randall

Edited by randallc
Link to comment
Share on other sites

the problem is that _ArrayDisplay() might waste a lot more memory than is necessary. This probably won't be an issue in most cases, but believe me, I've tested LARGE arrays before, and AutoIt ended up complaining that my system (which has 2GB) was out of RAM (and the AutoIt process really was using almost 2GB of RAM).

Hi,

So maybe you should do this without declaring a new array at all, as you are doubling memory usage?

Func _ArrayDisplayCurrNew(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|")
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)

    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    Local $timer = TimerInit()
    If $iDimension > 2 Then Return SetError(2, 0, 0)

    ; Separator handling
    If $sSeparator = "" Then $sSeparator = Chr(1)

    ; Declare variables
    Local $i, $j, $vTmp, $aItem, $avArrayText, $sHeader = "Row", $iBuffer = 2048000
    Local $iColLimit = 200, $iLVIAddUDFThreshold = 4000, $iWidth = 640, $iHeight = 480
    Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)

    ; Swap dimensions if transposing
    If $iSubMax < 0 Then $iSubMax = 0
    If $iTranspose Then
        $vTmp = $iUBound
        $iUBound = $iSubMax
        $iSubMax = $vTmp
    EndIf

    ; Set limits for dimensions
    If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
    If $iItemLimit = 1 Then $iItemLimit = $iLVIAddUDFThreshold
    If $iItemLimit < 1 Then $iItemLimit = $iUBound
    If $iUBound > $iItemLimit Then $iUBound = $iItemLimit
    If $iLVIAddUDFThreshold > $iUBound Then $iLVIAddUDFThreshold = $iUBound

    ; Set header up
    For $i = 0 To $iSubMax
        $sHeader &= $sSeparator & "[" & $i & "]"
    Next
    Local  $iArrayType = $iDimension + 2 * $iTranspose - 1, $sTxt
;~     ; Convert array into text for listview
    local $iDiffLen=(StringLen($sReplace)-StringLen($sSeparator))
    For $i = ($iLVIAddUDFThreshold + 1) To $iUBound - 1
        $vTmp=0
        Switch $iArrayType   ;   $iDimension + 2 * $iTranspose - 1
            Case 0 ;1D
                For $j = 0 To $iSubMax; Add to text array [$iSubMax]
                    $vTmp += StringLen($avArray[$i])
                Next
            Case 1 ;2D
                For $j = 0 To $iSubMax; Add to text array
                    $vTmp +=StringLen($avArray[$i][$j])
                Next
            Case 2 ;1DT
                For $j = 0 To $iSubMax; Add to text array
                    $vTmp+= StringLen($avArray[$j])
                Next
            Case 3 ;2DT
                For $j = 0 To $iSubMax; Add to text array
                    $vTmp+= StringLen($avArray[$j][$i])
                Next
        EndSwitch
        $vTmp+=($j)*$iDiffLen 
        If $vTmp> $iBuffer Then $iBuffer = $vTmp
    Next
    $iBuffer += 1

    ; GUI Constants
    Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66
    Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40
    Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200
    Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2
    Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4
    Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
    Local Const $_ARRAYCONSTANT_LVIF_PARAM = 0x4
    Local Const $_ARRAYCONSTANT_LVIF_TEXT = 0x1
    Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
    Local Const $_ARRAYCONSTANT_LVM_INSERTITEMA = (0x1000 + 7)
    Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
    Local Const $_ARRAYCONSTANT_LVM_SETITEMA = (0x1000 + 6)
    Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
    Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
    Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
    Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
    Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
    Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
    Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000
    Local Const $_ARRAYCONSTANT_tagLVITEM = "int Mask;int Item;int SubItem;int State;int StateMask;ptr Text;int TextMax;int Image;int Param;int Indent;int GroupID;int Columns;ptr pColumns"

    Local $iAddMask = BitOR($_ARRAYCONSTANT_LVIF_TEXT, $_ARRAYCONSTANT_LVIF_PARAM)
    Local $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]"), $pBuffer = DllStructGetPtr($tBuffer)
    Local $tItem = DllStructCreate($_ARRAYCONSTANT_tagLVITEM), $pItem = DllStructGetPtr($tItem)
    DllStructSetData($tItem, "Param", 0)
    DllStructSetData($tItem, "Text", $pBuffer)
    DllStructSetData($tItem, "TextMax", $iBuffer)

    ; Set interface up
    Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
    Local $aiGUISize = WinGetClientSize($hGUI)
    Local $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
    Local $hCopy = GUICtrlCreateButton("Copy Selected", 3, $aiGUISize[1] - 23, $aiGUISize[0] - 6, 20)

    GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
    GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
    GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)

    ; Fill listview
    For $i = 0 To $iLVIAddUDFThreshold;$iUBound
        $stmp = "[" & $i & "]" 
        Switch $iArrayType   ;   $iDimension + 2 * $iTranspose - 1
            Case 0 ;1D
                For $j = 0 To $iSubMax; Add to text array [$iSubMax]
                    $stmp &= $sSeparator & StringReplace($avArray[$i], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Next
            Case 1 ;2D
                For $j = 0 To $iSubMax; Add to text array
                    $stmp &= $sSeparator & StringReplace($avArray[$i][$j], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Next
            Case 2 ;1DT
                For $j = 0 To $iSubMax; Add to text array
                    $stmp &= $sSeparator & StringReplace($avArray[$j], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Next
            Case 3 ;2DT
                For $j = 0 To $iSubMax; Add to text array
                    $stmp &= $sSeparator & StringReplace($avArray[$j][$i], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Next
        EndSwitch
        GUICtrlCreateListViewItem($stmp, $hListView)

    Next
    
    If $iDimension = 1 Then $iNumItems = 2
    If $iDimension = 2 Then $iNumItems = UBound($avArray, 2 - $iTranspose) + 1

    For $i = ($iLVIAddUDFThreshold + 1) To $iUBound
        DllStructSetData($tBuffer, "Text", "[" & $i & "]")

        ; Add listview item
        DllStructSetData($tItem, "Item", $i)
        DllStructSetData($tItem, "SubItem", 0)
        DllStructSetData($tItem, "Mask", $iAddMask)
        GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_INSERTITEMA, 0, $pItem)

        ; Set listview subitem text
        DllStructSetData($tItem, "Mask", $_ARRAYCONSTANT_LVIF_TEXT)
        For $j = 2 - $iDimension To $iNumItems - $iDimension
            Switch $iArrayType   ;   $iDimension + 2 * $iTranspose - 1
                Case 0 ;1D
                    $sTxt = StringReplace($avArray[$i], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Case 1 ;2D
                    $sTxt = StringReplace($avArray[$i][$j], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Case 2 ;1DT
                    $sTxt = StringReplace($avArray[$j], $sSeparator, $sReplace, 0, 1);$sSeparator &
                Case 3 ;2DT
                    $sTxt = StringReplace($avArray[$j][$i], $sSeparator, $sReplace, 0, 1);$sSeparator &
            EndSwitch
            DllStructSetData($tBuffer, "Text", $sTxt)
            DllStructSetData($tItem, "SubItem", $j - 1 + $iDimension)
            GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETITEMA, 0, $pItem)
        Next
    Next

    ; Show dialog
    GUISetState(@SW_SHOW, $hGUI)
    ConsoleWrite("_ArrayDisplayCurrNew ="&TimerDiff($timer) / 1000 & @CRLF)
    While 1
        Switch GUIGetMsg()
            Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
                ExitLoop

            Case $hCopy
                Local $sClip = ""

                ; Get selected indices [ _GUICtrlListView_GetSelectedIndices($hListView, True) ]
                Local $aiCurItems[1] = [0]
                For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
                    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then
                        $aiCurItems[0] += 1
                        ReDim $aiCurItems[$aiCurItems[0] + 1]
                        $aiCurItems[$aiCurItems[0]] = $i
                    EndIf
                Next

                ; Generate clipboard text
                If Not $aiCurItems[0] Then
                    For $sItem In $avArrayText
                        $sClip &= $sItem & @CRLF
                    Next
                Else
                    For $i = 1 To UBound($aiCurItems) - 1
                        $sClip &= $avArrayText[$aiCurItems[$i]] & @CRLF
                    Next
                EndIf
                ClipPut($sClip)
        EndSwitch
    WEnd
    GUIDelete($hGUI)

    Opt("GUIOnEventMode", $iOnEventMode)
    Opt("GUIDataSeparatorChar", $sDataSeparatorChar)

    Return 1
EndFunc   ;==>_ArrayDisplay
Best, Randall

[PS 5% faster, too, maybe...]

[PS 2 - have to fix the copy to clip if used...]

Edited by randallc
Link to comment
Share on other sites

No, that's still not a fair comparison. A fair comparison happens only when the output from both things being compared are as close as possible. Again, using the same character for replacement as GUIDataSeparatorChar will cause an improper display; columns will get shifted over for any row that contains the replacement character. Although chr(1) is a non-printable character, when other columns get pushed over, the user might think something is in a particular column when Hi,

I don't think this argument is valid. If someone must deliberatly invoke an option to ignore that possibility, or if we warned in instructions that "null" characters in the arrya would not be replaced by default, I think the person geting a problem from it is

1. Rare, or

2. Asking knowingly

what do you think?

Randall

Link to comment
Share on other sites

You can make an accurate square root function, and I can make an inaccurate one that simply returns 1. Sure, simply returning 1 is way faster than actually calculating the square root, but that doesn't make it a better function. That's a wildly overexaggerated example, but the point is, if you want to compare speed, the output must be (at least approximately) identical, be acceptable, and shouldn't affect the end user unexpectedly. Otherwise you're comparing apples to oranges.

Whether it performs faster because a user chooses certain arguments as input is a different question. I'll think it over again.

Regarding memory usage, copying the array doesn't use that much memory. It'll double the memory used by the array, but that's chump change compared to how much memory a listview with lots of items will use. How much memory the listview was using was the point, not memory usage of the function overall. Again, that's why I chose to allow the buffer size to increase slightly in the first place -- because memory usage isn't my top priority unless it's too excessive. You're still ignoring the fact that splitting the code up the way you have it makes it less maintainable. Again, if every sliver of performance were such an issue to me, I might as well revert the change I made here and reclaim the 8% I deliberately took away.

Edited by -Ultima-

[ WinINet.au3 | Array.au3 (Optimized) | _UnixTimeParse() ]

Link to comment
Share on other sites

You can make an accurate square root function, and I can make an inaccurate one that simply returns 1. Sure, simply returning 1 is way faster than actually calculating the square root, but that doesn't make it a better function. That's a wildly overexaggerated example, but the point is, if you want to compare speed, the output must be (at least approximately) identical, be acceptable, and shouldn't affect the end user unexpectedly. Otherwise you're comparing apples to oranges.

Whether it performs faster because a user chooses certain arguments as input is a different question. I'll think it over again.

Regarding memory usage, copying the array doesn't use that much memory. It'll double the memory used by the array, but that's chump change compared to how much memory a listview with lots of items will use. How much memory the listview was using was the point, not memory usage of the function overall. Again, that's why I chose to allow the buffer size to increase slightly in the first place -- because memory usage isn't my top priority unless it's too excessive. You're still ignoring the fact that splitting the code up the way you have it makes it less maintainable. Again, if every sliver of performance were such an issue to me, I might as well revert the change I made here and reclaim the 8% I deliberately took away.

Hi,

I see. OK,

Best, Randall

Link to comment
Share on other sites

I just realized that we need a new array function unless someone has already done it and I missed the post.

_ArrayGetDim($vArray)

to return the number of dimensions in an array.

Has it already been done?

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Link to comment
Share on other sites

  • Developers

I just realized that we need a new array function unless someone has already done it and I missed the post.

_ArrayGetDim($vArray)

to return the number of dimensions in an array.

Has it already been done?

George,

Which part are you missing in the build-in Ubound version ?

$rows = UBound($myArray)
$cols = UBound($myArray, 2)
$dims = UBound($myArray, 0)

:D

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...