I have run the code in the first post with these results:
 
Time to run with AdlibRegistered: 14571.9029530593
Time to run with AdlibUnRegistered: 13025.2308415184
Time to run with AdlibRegistered to _FakeTray: 13365.1403195613
	 
 
	A few comments:
 
		A large number of loops are much faster in 64 bit code.
	
	
		The outer loop (j-loop) is always faster in second and third passes. In this code about 1 second faster. This gives incorrect results. It should be taken into account by introducing an initial first run.
	
	
		$aSmallerArray is not be reset between each pass.
	
	
		Tooltip: If Not Mod( $i, 20736 ) Then ToolTip("We are " & $i/20736 & "% done", 0, 0)
	
	
		Added _ArrayDisplayEx that can display large arrays
	
	New code:
 
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include "Display\Functions\ArrayDisplayEx\ArrayDisplayEx.au3"
Global $iBlockSize = 20, $iWidth = 1920, $iHeight = 1080, $iIndexLength = $iWidth * $iHeight, $iPercentDone, $sLastMsg
Global $aBigArray[$iIndexLength],  $aSmallerArray[$iWidth / $iBlockSize * $iHeight / $iBlockSize]
Global $sAdlib = [" First run: ", "Registered: ", "UnRegistered: ", "Registered to _FakeTray: "]
Global $ixBlocks = $iWidth / $iBlockSize, $iBlockIndex, $iBlockX, $iBlockY, $timer, $x, $y
For $j = 0 To 3
    If $j = 1 Then
        AdlibRegister("_CheckTray", 100)
    ElseIf $j = 2 Then
        AdlibUnRegister("_CheckTray")
    ElseIf $j = 3 Then
        AdlibRegister("_FakeTray", 100)
    EndIf
    $aSmallerArray = 0
    Dim $aSmallerArray[$iWidth / $iBlockSize * $iHeight / $iBlockSize]
    $timer = TimerInit()
    For $i = 0 To $iIndexLength - 1 ; Loop through $aBigArray
        $aBigArray[$i] = Random(1, 10, 1)
        If Not Mod( $i, 20736 ) Then ToolTip("We are " & $i/20736 & "% done", 0, 0)
        $y = Floor($i / $iWidth) ; Convert index to Y coordinate
        $x = Floor($i - ($y * $iWidth)) ; Convert index to X coordinate
        $iBlockX = Floor($x / $iBlockSize) ; Convert X coord to xBlock coord
        $iBlockY = Floor($y / $iBlockSize) ; Convert Y coord to yBlock coord
        $iBlockIndex = Int($iBlockX + ($iBlockY * $ixBlocks)) ; Convert into a blockIndex
        $aSmallerArray[$iBlockIndex] += Int($aBigArray[$i]) ; Add into $aSmallerArray
    Next
    ConsoleWrite("Time to run with Adlib" & $sAdlib[$j] & TimerDiff($timer) & @CRLF)
Next
Global $aWidth = [ 0, 65 ]
Global $aAlign = [ [ 0, "l" ], [ 1, "r" ] ]
Global $aFeatures = [ [ "ColWidthMin", $aWidth ], _
                     [ "ColAlign",    $aAlign ] ]
_ArrayDisplayEx( $aBigArray, "$aBigArray", "", 0, $aFeatures )
_ArrayDisplayEx( $aSmallerArray, "$aSmallerArray", "", 0, $aFeatures )
Func _CheckTray()
    Switch TrayGetMsg()
        Case "Meow"
            Return
        Case "Woof"
            Return
    EndSwitch
EndFunc   ;==>_CheckTray
Func _FakeTray()
    Local $sMeow = "Oink"
    Switch $sMeow
        Case "Meow"
            Return
        Case "Woof"
            Return
    EndSwitch
EndFunc   ;==>_FakeTray
Exit
#cs
Time to run with Adlib First run: 9354.58487313101
Time to run with AdlibRegistered: 8572.65596364715
Time to run with AdlibUnRegistered: 8436.5804675481
Time to run with AdlibRegistered to _FakeTray: 8573.66191708517
#ce
	And results:
 
Time to run with Adlib First run: 9354.58487313101
Time to run with AdlibRegistered: 8572.65596364715
Time to run with AdlibUnRegistered: 8436.5804675481
Time to run with AdlibRegistered to _FakeTray: 8573.66191708517
	Now there is not much difference between the last 3 results.
 
	 
 
	For arrays with 2 million elements, it's a great advantage to use compiled code. Since UDFs already exist to execute VB code (and C# code) in an AutoIt script through the .NET Framework, it's not difficult.
 
	c.vb:
 
Imports System
Class Au3Class
  Dim aSmallerArray As Integer()
  Public Function MyMethod1( iBlockSize As Integer, iWidth As Integer, iHeight As Integer ) As Integer()
    Dim ixBlocks As Integer = iWidth / iBlockSize
    ReDim aSmallerArray(ixBlocks * iHeight/iBlockSize - 1)
    Dim iIndexLength As Integer = iWidth * iHeight
    Dim aBigArray(iIndexLength-1) As Integer
    Dim oRnd As New Random()
    Dim x, y, iBlockX, iBlockY, iBlockIndex As Integer
    For i As Integer = 0 To iIndexLength - 1
      aBigArray(i) = oRnd.Next( 1, 10+1 )
      y = Math.Floor( i / iWidth ) : x = Math.Floor( i - y * iWidth )
      iBlockX = Math.Floor( x / iBlockSize ) : iBlockY = Math.Floor( y / iBlockSize )
      iBlockIndex = iBlockX + iBlockY * ixBlocks
      aSmallerArray(iBlockIndex) += aBigArray(i)
    Next
    Return aBigArray
  End Function
  Public Function MyMethod2() As Integer()
    Return aSmallerArray
  End Function
End Class
	c.au3:
 
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include "DotNet\DotNetAll.au3"
#include "Display\Functions\ArrayDisplayEx\ArrayDisplayEx.au3"
Opt( "MustDeclareVars", 1 )
Example()
Func Example()
  Local $oNetCode = DotNet_LoadVBcode( FileRead( "c.vb" ), "System.dll" )
  Local $oAu3Class = DotNet_CreateObject( $oNetCode, "Au3Class" )
  Local $timer = TimerInit()
  Local $aBigArray = $oAu3Class.MyMethod1( 20, 1920, 1080 )
  Local $aSmallerArray = $oAu3Class.MyMethod2()
  ConsoleWrite( TimerDiff( $timer ) & @CRLF ) ; 221.589018567889
  Local $aWidth = [ 0, 65 ]
  Local $aAlign = [ [ 0, "l" ], [ 1, "r" ] ]
  Local $aFeatures = [ [ "ColWidthMin", $aWidth ], _
                       [ "ColAlign",    $aAlign ] ]
  _ArrayDisplayEx( $aBigArray, "$aBigArray", "", 0, $aFeatures )
  _ArrayDisplayEx( $aSmallerArray, "$aSmallerArray", "", 0, $aFeatures )
EndFunc
	Note the time: 221 milliseconds.
 
	 
 
	You cannot do anything about the Sleep function in TrayGetMsg() and GUIGetMsg(), but you can completely avoid the functions by using Windows messages directly through GUIRegisterMsg() (still in MessageLoop mode).
 
	 
 
	Tests.7z