I'm using the standard Let-notation function "#" to try and create a dictionary from a very large list of approx. 500,000 primary key IDs. However, it is taking almost a minute to process.
Set Variable [ $dictionary = #("pkIdList" ; $listOfPkIds) ]
When I build the dictionary manually using Quote(), it is done in a few seconds. If I take the quoted list (of ~500,000 IDs) and try to add it, it takes just about as long.
Set Variable [ $quotedPkIds = Quote ( $listOfPkids ) ] // this takes a couple of seconds
Set Variable [ $manualDictionary = "$pkIdList = " & $quotedPkIds & ";¶" ] // this is instant
Set Variable [ $dictionary = #("pkIdList" ; $quotedPkIds) ] // this still takes almost a minute
I'm not sure what part of the #() function is causing the slowdown; I'm guessing it's something that secretly operates recursively under the hood, but I still don't fully grok the internals of #(). Any suggestions on what I should look at or what can be optimized?
Here's the internals of #() for reference. Thanks!
/**
* =====================================
* # ( name ; value )
*
* RETURNS:
* An name-value pair in Let notation.
*
* PARAMETERS:
* name: The name for the returned name-value pair. name can be any value
* that would be a valid Let() variable name.
* value: The value for the returned name-value pair.
*
* EXAMPLE:
* # ( "name"; $value ) & # ( "foo" ; "bar" )
*
* DEPENDENCIES: none
*
*
* REFERENCES:
* https://github.com/filemakerstandards/fmpstandards/blob/master/Functions/%23Name-Value/%23.fmfn
* =====================================
*/
Let ( [
~name = // strip leading "$$" and "$"
Substitute (
"/*start*/" & name ;
[ "/*start*/$$" ; "" ] ;
[ "/*start*/$" ; "" ] ;
[ "/*start*/" ; "" ]
) ;
~plusOneText = GetAsText ( value + 1 ) ;
~isValidDate = not EvaluationError ( GetAsDate ( value ) ) ;
~isValidTime = not EvaluationError ( GetAsTime ( value ) ) ;
~number = GetAsNumber ( value ) ;
~value =
Case (
value = "" or value = "?" or ~number = "?" ;
Quote ( value ) ;
~isValidDate
and ~isValidTime
and GetAsText ( GetAsTimestamp ( value ) + 1 ) = ~plusOneText ;
"GetAsTimestamp ( " & Quote ( value ) & " )" ;
~isValidTime
and GetAsText ( GetAsTime ( value ) + 1 ) = ~plusOneText ;
"GetAsTime ( " & Quote ( value ) & " )" ;
~isValidDate
and GetAsText ( GetAsDate ( value ) + 1 ) = ~plusOneText ;
"GetAsDate ( " & Quote ( value ) & " )" ;
value ≠ ~number ;
Quote ( value ) ;
/* Else */
~number
) ;
~result =
"$"
& ~name
& " = "
& ~value
& " ;¶" ;
~testExpression =
"Let ( [ "
& ~result
& " ~ = \"\" ]; \"\" )" ;
~error =
Case (
IsEmpty ( ~name ) or Position ( ~name ; ¶ ; 1 ; 1 ) ≠ 0 ;
11 ; // Name is not valid
not IsValidExpression ( ~testExpression ) ;
1200 // Generic calculation error
)
];
If ( ~error ; // prevent bad pairs from affecting evaluation by commenting
"/* Error "
& ~error
& " name: "
& Quote (
Substitute ( // escape comment character sequences
name ;
[ "*/" ; "\*\/" ] ;
[ "/*" ; "\/\*" ]
)
)
& " value: "
& Quote (
Substitute ( // escape comment character sequences
value ;
[ "*/" ; "\*\/" ] ;
[ "/*" ; "\/\*" ]
)
)
& " */"
& ¶ ;
/* Else */
~result
)
)