Vitaliy Serdtsev · Nov 20, 2025 go to post
json=[
{"s":"iPhone1"},
{"s":"iPhone2"},
{"s":"IPHONE3"},
{"s":"IPHONE4"},
{"s":"Phone5"}
]

##class(%ASQ.SetUtils).pp(json.apply("$[*]?(@.s like_regex '\p{LL}\w+')"))

Output (IRIS 2025.3CE):

[
  {
    "s": "iPhone1"
  },
  {
    "s": "iPhone2"
  }
]
Vitaliy Serdtsev · Nov 20, 2025 go to post

Check the result outputs of the following code from Studio and from Terminal:

<FONT COLOR="#0000ff">w $zu</FONT><FONT COLOR="#000000">(67,13,</FONT><FONT COLOR="#0000ff">$j</FONT><FONT COLOR="#000000">)</FONT>

Vitaliy Serdtsev · Nov 13, 2025 go to post

A long time ago, back in the days of Caché, I made a series of articles on creating a web application based on REST and CSP with my own static file processing. Try it, maybe you can use something from there.

Vitaliy Serdtsev · Nov 13, 2025 go to post

I will assume that you are using "Normal" (in which the user _SYSTEM is turned off) or even "Locked Down" (the user "UnknownUser" has no roles at all): Initial User Security SettingsDOC

I'm using "Locked Down", IRIS 2025.2CE and ran into a lot of different bugs when using WebTerminal v4.9.5:

  • <PROTECT>endSession+25^%SYS.cspServer
  • <LICENSE LIMIT EXCEEDED>
  • etc.
Fortunately, the WebTerminal source code is available for analysis and editing.

The problem can be solved in two ways: either fix the source code or add the missing role. I chose the latter.

In my case, it is enough for the web application /terminalsocket to add the %Admin_Secure role in addition to the existing roles. After that, it doesn't hurt to clean up all existing sessions:

kill ^WebTerminal("AuthUser")

If the <LICENSE LIMIT EXCEEDED> error persists after this, restart the IRIS instance.

PS: Advisory for IRISSECURITY in InterSystems IRIS 2025.2

Vitaliy Serdtsev · Nov 13, 2025 go to post

Credentials are not requested, as most likely your existing session has not expired yet. By default, the timeout is 1 hour (see the "WebTerminal.Engine:WSKEYEXPIRES" class parameter).

Vitaliy Serdtsev · Nov 5, 2025 go to post

I would venture to assume that this difference is due to the overhead of calling the class method. In other words:

  • ##class(%DynamicArray).%New() -> ..%OnNew() -> $ZU()
  • [] -> $ZU()
There was a similar topic: Shared code execution speed
Vitaliy Serdtsev · Oct 31, 2025 go to post
"Real life" *.inc entry is to execute macro routine "Entry^HS.Local.VA.Util.Log(%arr,,"D")" if Global ^GlFSL("Debug") is >0 by calling from a classmethod as $$$TestIf(arr) - no return value is required.
#define TestIf(%arr) if (^GlFSL("Debug")>0) {do Entry^HS.Local.VA.Util.Log(%arr,,"D")}
;or
#define TestIf(%arr) do:^GlFSL("Debug")>0 Entry^HS.Local.VA.Util.Log(%arr,,"D")
Usage:
$$$TestIf(5)
Vitaliy Serdtsev · Oct 31, 2025 go to post
Statement "set a = $$$TestIf(3)" is included into a classmethod with no other code in. Expected output 5
What is the expected result for the next operator?
set $$$TestIf(-3)
Vitaliy Serdtsev · Oct 30, 2025 go to post

You have two mistakes.

  • Instead
    for {i=1:1:%count set x=
    should be
    for i=1:1:%count {set x=
  • Macros ≠ Function

A working example:

  #define MyLoop(%count,%result) set ref="",%result="" for i=1:1:%count set ref=$order(^%SYS("JOURNAL",ref),-1),%result=%result_$listbuild(ref)

  $$$MyLoop(5,x)
  write $listtostring(x)
Vitaliy Serdtsev · Oct 30, 2025 go to post

Example of @Robert Cemper compiles without errors for me (even on Caché 2018.xxx):

Class dc.a Abstract ]
{

ClassMethod Test()
{
  #define MyLoop(%count) set x="" for i=1:1:%count set x=$order(^%SYS("JOURNAL",x),-1) write x,! 
  $$$MyLoop(5)
}

}
Vitaliy Serdtsev · Oct 30, 2025 go to post

If the array is multidimensional, then you can't do without loops (the code is without error handling):

  #define ArrayToStr(%arr,%str) set ref=$name(%arr),%str="s " for  {set ref=$query(@ref,1,val) quit:ref=""  set %str=%str_$$FormatName^%qcr(ref,1)_"="_##class(%Utility).FormatString(val)_","} set $extract(%str,*)=""
  #define StrToArray(%str) xecute %str

Usage:

  set a(0)=7
  set a(1,"color")="green"
  set a(1,"color","green")=""
  set a("color",$listbuild($double(3)))=$listbuild("red","blue")

  $$$ArrayToStr(a,str)
  zwrite str
  kill a
  $$$StrToArray(str)
  zwrite a
Vitaliy Serdtsev · Oct 30, 2025 go to post
I would like to have *inc file entry to convert an array into a string and string into an array.
If the array is one-dimensional, then you can do without cycles altogether. I'll give you a small example below:
  #define Array1ToJSONString(%arr,%json)##continue
  s ##unique(new)=##class(%ZEN.proxyObject).%New()##continue
  d ##unique(old).%CopyFromArray(.%arr),##continue
    ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.%json,##unique(old))##continue
  s %json=%json.Read(3641144)
  
  #define JSONStringToArray1(%json,%arr)##continue
  d ##class(%ZEN.Auxiliary.altJSONProvider).%ConvertJSONToObject(%json,,.##unique(new)),##continue
    ##unique(old).%CopyToArray(.%arr)

Usage:

  set a("color")=$listbuild("red","blue")
  set a("price")="expensive"
  set a("size")=$listbuild("large","small")
    
  $$$Array1ToJSONString(a,jsonStr)
  zwrite jsonStr
  $$$JSONStringToArray1(jsonStr,b)
  zwrite b
Vitaliy Serdtsev · Oct 29, 2025 go to post
Attention: You can INCLUDE just 1 single *.INC in a class definition.
Including Include Files

To include multiple include files at the beginning of a class definition, the syntax is of the form:

Include (MyMacros, YourMacros)
Vitaliy Serdtsev · Aug 21, 2025 go to post
import iris

# first, we connect to the %SYS namespace
conn = iris.connect('localhost:1972/%SYS','_SYSTEM',pwd,10,True)
irispy = iris.createIRIS(conn)

# here we switch to the USER namespace
newNameSpace = irispy.classMethodString('%SYSTEM.Process','SetNamespace','USER')

# now we can call the method from the new namespace
#print(irispy.classMethodInteger('DC.Unix','RoundPosixToSeconds',1154669852181849976))

conn.close()
Vitaliy Serdtsev · Aug 15, 2025 go to post
#Include %sqlx
set newposix $$$sqlxPosixTimeEncode(+$p($$$sqlxPosixTimeDecode(posix),".",1))

Сheck:

<FONT COLOR="#0000ff">for </FONT><FONT COLOR="#808000">posix </FONT><FONT COLOR="#000000">= 1154669852181849976, -6979664624441081856, 1406323805406846975 </FONT><FONT COLOR="#800080">{

  </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">newposix </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$sqlxPosixTimeEncode</FONT><FONT COLOR="#000000">(+</FONT><FONT COLOR="#0000ff">$p</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$$$sqlxPosixTimeDecode</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">posix</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">"."</FONT><FONT COLOR="#000000">,1))

  </FONT><FONT COLOR="#0000ff">write </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%PosixTime</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">LogicalToTimeStamp</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">posix</FONT><FONT COLOR="#000000">),!,         </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%PosixTime</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">LogicalToTimeStamp</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">newposix</FONT><FONT COLOR="#000000">),!! </FONT><FONT COLOR="#800080">}</FONT>

2025-05-27 12:06:15.003 2025-05-27 12:06:15

0001-01-01 00:00:00 0001-01-01 00:00:00

9999-12-31 23:59:59.999999 9999-12-31 23:59:59

Vitaliy Serdtsev · Aug 11, 2025 go to post
 

source code of dc.observation_lab

Class dc.a Extends %Persistent SqlTableName observation_lab ]
{

Index iCode On code;

Index iCodeText On codetext;

Property code As %String(MAXLEN 2000);

Property codetext As %String(MAXLEN 2000) [ SqlFieldName code_1_text ];

/// d ##class(dc.a).Test()
ClassMethod Test(= {5e6})
{
  t=$zh
  d DISABLE^%NOJRN
  ^dc.aD,^dc.aI
  i=1:1:c=i-1#1000+1,^dc.aD(i)=$lb("",c,"code_1_text_"_c)
  ^dc.aD=N
  ENABLE^%NOJRN
  "(time) insert = ",$zh-t,!
  
  t=$zh
  d ..%BuildIndices(,,,$$$NO)
  "(time) %BuildIndices = ",$zh-t,!
  
  t=$zh
  d $system.SQL.TuneTable("dc.observation_lab",,1,,,,,,,"100%")
  ;&sql(TUNE TABLE dc.observation_lab %SAMPLE_PERCENT '100%')
  "(time) tune table = ",$zh-t,!
}

}

The following query does not use iCode/iCodeText indexes (2025.2.CE):

select code_1_textcount(code_1_text)
  from dc.observation_lab
  group by code_1_text
  order by desc

PS: if possible, I would try to convert the text into a number in some way and index this number already, perhaps even with the bitmap type.

Vitaliy Serdtsev · Aug 4, 2025 go to post

I completely agree with you.👍

I hope someone from InterSystems will pay attention to your post.

PS: and in addition, it would also be nice to solve the issue with %FromOref(): either the code or the documentation needs to be fixed. On version 2025.2.CE it still doesn't work.

Vitaliy Serdtsev · Aug 4, 2025 go to post

Here explained to us that this is not a bug, but a feature: <PROTECT> *Function not allowed in IRIS Native python

Starting from 2024.1 IRIS Native disallows routine invocations. Please use class methods instead.

For reference, these changes can be identified as DP-422635 and DP-424156.

PS: and yes, additional roles and resources like %Native_*/%All etc. no eliminate the <PROTECT> error. Checked on version 2025.2.CE

Vitaliy Serdtsev · Jul 16, 2025 go to post

Very strange syntax:

But if we tried at once with a single statment with a select into (1 value) it fails
<FONT COLOR="#0000ff">INSERT </FONT><FONT COLOR="#000080">INTO </FONT><FONT COLOR="#008000">Sample</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">YoungPeople </FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">PASReligionCode</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values </FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">SELECT </FONT><FONT COLOR="#008000">internalPatientNumber </FONT><FONT COLOR="#000080">FROM
</FONT><FONT COLOR="#008000">Pennine_TIE_Clinicom_Link</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">PMISPECIALREGNCA </FONT><FONT COLOR="#000080">where </FONT><FONT COLOR="#008000">InternalPatientNumber</FONT><FONT COLOR="#000000">=100)</FONT>
See:
Vitaliy Serdtsev · Jun 30, 2025 go to post

Yes. Or you can immediately increase the logical size of the IRISTEMP to the desired value, for example:

%SYS>set status=##class(Config.Databases).Get("IRISTEMP",.props)
%SYS>set status=##class(SYS.Database).ModifyDatabase(props("Directory"),5*1024) ; 5Gb

In this case, you will immediately increase the size from 240Mb to 5Gb, bypassing many small expansions.

Vitaliy Serdtsev · Jun 13, 2025 go to post

I simplified the code a bit for testing:

ROUTINE ztest23
<FONT COLOR="#ff0000">Version</FONT><FONT COLOR="#000000">()  </FONT><FONT COLOR="#0000ff">quit </FONT><FONT COLOR="#000000">20250613
  </FONT><FONT COLOR="#008000">;
  ; do init^ztest22(100)  ; in one irissession
  ;
  ; in another irissession:
  ; do test^ztest23()
  ;

</FONT><FONT COLOR="#ff0000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#ff00ff">N</FONT><FONT COLOR="#000000">=1E7) </FONT><FONT COLOR="#0000ff">public </FONT><FONT COLOR="#800080">{   </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest23(</FONT><FONT COLOR="#008000">"convertInRunFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#ff00ff">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">),      </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest23(</FONT><FONT COLOR="#008000">"convertInBigMacFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#ff00ff">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">write $fnumber</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">*100/</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">,2)_</FONT><FONT COLOR="#008000">"% difference"</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#800080">}

</FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#ff00ff">pLabel</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#ff00ff">N</FONT><FONT COLOR="#000000">=1E7,&</FONT><FONT COLOR="#ff00ff">dt</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">public </FONT><FONT COLOR="#008000">; kill dt do runOne^ztest23("convertInRunFar",1E7,.dt) </FONT><FONT COLOR="#800080">{   </FONT><FONT COLOR="#0000ff">if </FONT><FONT COLOR="#ff00ff">pLabel</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"convertInRunFar" </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">comment</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"looping $$convertIn^ztestLib (far)"   </FONT><FONT COLOR="#800080">}</FONT><FONT COLOR="#0000ff">else</FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">comment</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"%New^ztestBigMac, looping $$convertIn^ztestLib (far)"     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">convertName</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$$</FONT><FONT COLOR="#ff0000">%New</FONT><FONT COLOR="#000000">^ztestBigMac()   </FONT><FONT COLOR="#800080">}      </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">convertIny</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zconvert</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"Маленькая умная Коричневая Лиса прыгает через лежащую сонную Пятнистую Собаку"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"o"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"UTF8"</FONT><FONT COLOR="#000000">)      </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt0</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zhorolog  for </FONT><FONT COLOR="#808000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#ff00ff">N </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">convertInx</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">""   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt0</FONT><FONT COLOR="#000000">=(</FONT><FONT COLOR="#0000ff">$zhorolog</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt0</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zhorolog for </FONT><FONT COLOR="#808000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#ff00ff">N </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">convertInx</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$$</FONT><FONT COLOR="#ff0000">convertIn</FONT><FONT COLOR="#000000">^ztestLib(</FONT><FONT COLOR="#808000">convertIny</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"UTF8"</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#ff00ff">dt</FONT><FONT COLOR="#000000">=(</FONT><FONT COLOR="#0000ff">$zhorolog</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt0</FONT><FONT COLOR="#000000">)*1E6,</FONT><FONT COLOR="#ff00ff">dt</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#ff00ff">dt</FONT><FONT COLOR="#000000">/</FONT><FONT COLOR="#ff00ff">N   </FONT><FONT COLOR="#0000ff">write </FONT><FONT COLOR="#ff00ff">pLabel</FONT><FONT COLOR="#000000">,?30,</FONT><FONT COLOR="#0000ff">$fnumber</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#ff00ff">dt</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">,3),?45,</FONT><FONT COLOR="#808000">comment</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#800080">}</FONT>

Vitaliy Serdtsev · Jun 12, 2025 go to post

IRIS 2025.1 CE

I made 4 launches in a row - the result fluctuates greatly:

USER>set N=1E7 do runOne^ztest22("convertInRunFar",N,.fieldsset dt1=$get(fields("dt")) do runOne^ztest22("convertInBigMacFar",N,.fieldsset dt2=$get(fields("dt")) w $fn(dt2-dt1*100/dt1,"",2)_"% difference",!
convertInRunFar               0.473          looping $$convertIn^ztestLib (far)
convertInBigMacFar            0.478          %New^ztestBigMac, looping $$convertIn^ztestLib (far)
1.13% difference

USER><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">=1E7 </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInRunFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInBigMacFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">w $fn</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">*100/</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">,2)_</FONT><FONT COLOR="#008000">"% difference"</FONT><FONT COLOR="#000000">,!</FONT> convertInRunFar 0.474 looping $$convertIn^ztestLib (far) convertInBigMacFar 0.598 %New^ztestBigMac, looping $$convertIn^ztestLib (far) 25.99% difference

USER><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">=1E7 </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInRunFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInBigMacFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">w $fn</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">*100/</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">,2)_</FONT><FONT COLOR="#008000">"% difference"</FONT><FONT COLOR="#000000">,!</FONT> convertInRunFar 0.461 looping $$convertIn^ztestLib (far) convertInBigMacFar 0.597 %New^ztestBigMac, looping $$convertIn^ztestLib (far) 29.70% difference

USER><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">=1E7 </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInRunFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#ff0000">runOne</FONT><FONT COLOR="#000000">^ztest22(</FONT><FONT COLOR="#008000">"convertInBigMacFar"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#808000">N</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$get</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">fields</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"dt"</FONT><FONT COLOR="#000000">)) </FONT><FONT COLOR="#0000ff">w $fn</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#808000">dt2</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">*100/</FONT><FONT COLOR="#808000">dt1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">,2)_</FONT><FONT COLOR="#008000">"% difference"</FONT><FONT COLOR="#000000">,!</FONT> convertInRunFar 0.511 looping $$convertIn^ztestLib (far) convertInBigMacFar 0.551 %New^ztestBigMac, looping $$convertIn^ztestLib (far) <FONT COLOR="#ff0000">7.88%</FONT> difference

USER>

I'm afraid we can't do without the WRC.