Vitaliy Serdtsev · Jun 13, 2025 go to post

I simplified the code a bit for testing:

ROUTINE ztest23
Version()  quit 20250613
  ;
  ; do init^ztest22(100)  ; in one irissession
  ;
  ; in another irissession:
  ; do test^ztest23()
  ;

test(N=1E7) public {
  do runOne^ztest23("convertInRunFar",N,.dt1),
     runOne^ztest23("convertInBigMacFar",N,.dt2)
  write $fnumber(dt2-dt1*100/dt1,"",2)_"% difference",!
}

runOne(pLabel,N=1E7,&dtpublic ; kill dt do runOne^ztest23("convertInRunFar",1E7,.dt)
{
  if pLabel="convertInRunFar" {
    set comment="looping $$convertIn^ztestLib (far)"
  }else{
    set comment="%New^ztestBigMac, looping $$convertIn^ztestLib (far)"
    set convertName=$$%New^ztestBigMac()
  }
  
  set convertIny=$zconvert("Маленькая умная Коричневая Лиса прыгает через лежащую сонную Пятнистую Собаку","o","UTF8")
  
  set dt0=$zhorolog  for i=1:1:set convertInx=""
  set dt0=($zhorolog-dt0)
  set dt1=$zhorolog for i=1:1:set convertInx=$$convertIn^ztestLib(convertIny,"UTF8")
  set dt=($zhorolog-dt1-dt0)*1E6,dt=dt/N
  write pLabel,?30,$fnumber(dt,"",3),?45,comment,!
}
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>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.474          looping $$convertIn^ztestLib (far)
convertInBigMacFar            0.598          %New^ztestBigMac, looping $$convertIn^ztestLib (far)
25.99% difference
 
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.461          looping $$convertIn^ztestLib (far)
convertInBigMacFar            0.597          %New^ztestBigMac, looping $$convertIn^ztestLib (far)
29.70% difference
 
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.511          looping $$convertIn^ztestLib (far)
convertInBigMacFar            0.551          %New^ztestBigMac, looping $$convertIn^ztestLib (far)
7.88% difference
 
USER>

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

Vitaliy Serdtsev · Jun 12, 2025 go to post

See Zen Layout, Zen Style

Class dc.test Extends %ZEN.Component.page
{

XData Style {   <style type="text/css">   #mss {     width:200px;     height:100px;     overflow:auto;     border:2px solid DeepPink;     background-color: #E5E5E5;   }

  a.multiSelectSetCaption {     colorblue;     font-familyVerdana;     font-weightbold;   } </style> }

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen">   <multiSelectSet     id="mss"     sql="     select 1 id,'Apple' name     union select 2,'Banana'     union select 3,'Cherry'     union select 4,'Peach'     union select 5,'Peach'     union select 6,'Cherry'     union select 7,'Banana'     union select 8,'Apple'"   /> </page> }

}

Vitaliy Serdtsev · Jun 11, 2025 go to post

Recently I noticed under some posts that there seem to be comments (count > 0), but there are no comments or their number does not correspond to the actual one. Is this related to AI Bot?

Vitaliy Serdtsev · Jun 11, 2025 go to post

Unlike SQL, which has hints, IRIS Object Script has nothing similar. The only thing left to do is to tweak these settings. If you already have everything tuned, then probably the only thing left is to contact the WRC.

PS: Having a reproducible example here would be a big help with the experiments. I love detective problems like this :)

Vitaliy Serdtsev · Jun 11, 2025 go to post

Class dc.test Extends %ZEN.Component.page
{

ClientMethod selectMulti() [ Language = javascript ] {   var values zenPage.GetValues()      zenSetProp('mss','value',values); }

ClassMethod GetValues() As %String ZenMethod ] {   ; here select data according to a certain condition   &sql(   select LIST(idinto :r   from     (select id,'Apple' name     union     select 2,'Banana'     union     select 3,'Cherry'     union     select 4,'Peach')   where name['a'   )   quit ; return 2,4 }

ClientMethod saveMulti() [ Language = javascript ] {   var values zenGetProp('mss','value');   zenPage.SaveValues(values); }

ClassMethod SaveValues(values) [ ZenMethod ] {   set ^fruits=values }

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen">   <button caption="Select All" onclick="zen('mss').selectAll()"/>   <button caption="Select based on data from the database" onclick="zenPage.selectMulti();"/>   <button caption="Save" onclick="zenPage.saveMulti();"/>   <multiSelectSet     id="mss"     sql="select 1 id,'Apple' name union select 2,'Banana' union select 3,'Cherry' union select 4,'Peach'"   /> </page> }

}

Vitaliy Serdtsev · Jun 11, 2025 go to post

See Query Parameters

XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
{
  <page xmlns="http://www.intersystems.com/zen">
    <multiSelectSet
      sql="select 'Apple' union select 'Banana' union select 'Cherry'"
    />
  </page>
}

Vitaliy Serdtsev · Jun 9, 2025 go to post

Let's suppose two different routines use one and the same chunk of code. From the object-oriented POV, a good decision is to have this chunk of code in a separate class and have both routines call it. However, whenever you call code outside of the routine as opposed to calling code in the same routine, some execution speed is lost. For reports churning through millions of transactions this lost speed might be noticeable. Any advice how to optimize specifically speed?

What you are asking is very similar to Inline function in C.

In Caché, macros and/or preprocessor directives are great for this role. Especially if the code size is small: ObjectScript Macros and the Macro Preprocessor

In this case you will avoid the overhead of calling goto, do, job, xecute, etc.

 

Example (procedure "swap")

Class dc.a Extends %RegisteredObject
{

ClassMethod swap(
  ByRef x,
  ByRef y)
{
  tmp=x,x=y,y=tmp
}

/// d ##class(dc.a).Test()
ClassMethod Test(= {1e7})
{
  #define swap(%x,%y) s ##unique(new)=%x,%x=%y,%y=##unique(old)
  
  s a=3,b=7  
  
  t=$zh  f i=1:1:tmp=a,a=b,b=tmp
  "inline procedure",?20,$zh-t," sec",!
  
  t=$zh  f i=1:1:swap
  "just a procedure",?20,$zh-t," sec",!
  
  t=$zh  f i=1:1:$$$swap(a,b)
  "macros procedure",?20,$zh-t," sec",!

  t=$zh  f i=1:1:..swap(.a,.b)
  "class method",?20,$zh-t," sec",!

swap() tmp=a,a=b,b=tmp
}

}

 ;dc.a.1
 ;Generated for class dc.a.  Do NOT edit. 09.06.2025 00:00:00PM
 ;;00000000;dc.a
 ;
Test(Nmethodimpl s:'($d(N)#2) N=1e7
  a=3,b=7  
  t=$zh  f i=1:1:tmp=a,a=b,b=tmp
  "inline procedure",?20,$zh-t," sec",!
  t=$zh  f i=1:1:swap
  "just a procedure",?20,$zh-t," sec",!
  t=$zh  f i=1:1:%mmmu1=a,a=b,b=%mmmu1
  "macros procedure",?20,$zh-t," sec",!
  t=$zh  f i=1:1:..swap(.a,.b)
  "class method",?20,$zh-t," sec",!
swap() tmp=a,a=b,b=tmp }
swap(x,ymethodimpl {
  tmp=x,x=y,y=tmp }

When implementing a sorting algorithm doing lots of swaps, this can increase the execution speed.

PS: And yes, avoid passing input/output parameters and class methods due to the high overhead of calling them.

Vitaliy Serdtsev · Jun 6, 2025 go to post

CREATE FUNCTION inLike(str VARCHAR(50), lstLike VARCHAR(50))
RETURNS BIT
PROCEDURE
LANGUAGE OBJECTSCRIPT
{
  set res = 0, ptr = 0
  while $listnext(lstLike,ptr,v{
    &sql(select case when :str like :v then else end into :like)
    if like {
      set res = 1
      quit
    }
  }  
  quit res
}

Usage:

select * from CustomersTable where inLike(CustomerName,$LISTBUILD('%Mark%','%John%','%an%'))=1

Vitaliy Serdtsev · Jun 4, 2025 go to post

Has it worked before? If so, then most likely there were some changes in the OS at the file/registry level.

First, try to run on the command line (see Registering Files):

cd D:\DHC\DEVSOFTWARE\ENSEMBLE\BIN D:\DHC\DEVSOFTWARE\ENSEMBLE\BIN>RegFiles.bat ALL

If it doesn't help, try select Repair to repair problems with the instance such as missing or corrupt files or registry entries: Reinstalling or Uninstalling Caché

Vitaliy Serdtsev · May 21, 2025 go to post

Great, that's something.

Can you show the exact query text and the class source code for the SQLUser.PA_Person table?

Vitaliy Serdtsev · May 21, 2025 go to post

In your question, yesterday you published the mgstat results for slow and fast servers. Now it looks like you've deleted this data, since I can't see it. Could you return them?

I noticed a very significant difference there for two parameters, namely routinebuffers and numberofcpus.

Vitaliy Serdtsev · May 21, 2025 go to post

Try to do my example and report the results. Also, try to run your query not in win sql, but in the InterSystems Management Portal.

Vitaliy Serdtsev · May 21, 2025 go to post

Class dc.a Extends %Persistent
{

Property As %String;

ClassMethod Test() {   &sql(truncate table dc.a)

  &sql(insert into dc.a(svalues('Hello'))   ##class(%SQL.Statement).%ExecDirect(,"select * from dc.a").%Display()

  !   &sql(update dc.set s=s||' world' where %ID=1)   ##class(%SQL.Statement).%ExecDirect(,"select * from dc.a").%Display() }

}

USER>##class(dc.a).Test() ID s 1 Hello

1 Rows(s) Affected ID s 1 Hello world

1 Rows(s) Affected

Can we see the error number and error text?

Vitaliy Serdtsev · May 19, 2025 go to post

If that's correct, is there a way to configure the JDBC connection to interpret this data using EUC-KR encoding?
No: Caché JDBC Connection Properties But even if JDBC had encoding settings, it wouldn't help you, because the 8-bit version of Caché doesn't support Korean and doesn't know anything about EUC-KR/KSC5601.

PS: I would consider switching to the Unicode version of Caché, which already has support for the Korean language.

Vitaliy Serdtsev · May 16, 2025 go to post

However, when I access the data through the Cache Management Portal, Cache Terminal, VSC, or IntelliJ, the Korean text appears broken, as I mentioned earlier.

Give an example of what you see in globals in the InterSystems Management Portal:
System Explorer > Globals

Since you have an 8-bit version and not Unicode, you probably won't see the hieroglyphs (최봉남), but rather something similar to (ÃÖºÀ³²).

This is not corrupted data, just a string stored in KSC5601/EUC-KR encoding.

From Caché terminal (Unicode version, locale = korw (Korean, Korea, Unicode)):

USER>w $zcvt("최봉남","O","KSC5601")
ÃÖºÀ³²
USER>w $zcvt("ÃÖºÀ³²","I","KSC5601")
최봉남

The same on Java:

System.out.println(new String("최봉남".getBytes(Charset.forName("EUC-KR")), Charset.forName("ISO-8859-1"))); // ÃÖºÀ³²
System.out.println(new String("ÃÖºÀ³²".getBytes(StandardCharsets.ISO_8859_1), Charset.forName("EUC-KR")));   // 최봉남
Vitaliy Serdtsev · May 15, 2025 go to post

When I run below code in the Cache terminal, it returns 0, so it seems to be the 8-bit version.

That's what I thought. I have the Unicode version installed, the rusw locale, and there are no problems at all.

 

Example

Class dc.a Extends %Persistent
{
Index is On s;
Property As %String;

/// d ##class(dc.a).Test()
ClassMethod Test()
{
  t=..%New()
  t.s="최봉남"
  
  t.%Save()
}
}

From any JDBC client:

select * from dc.a
Result:
ID s
1 최봉남

(When I check from the Management Portal, it shows as Latin1. If there's a more accurate way to verify this, please let me know.)

In SMP: System Administration > Configuration > National Language Settings > Locale Definitions
You should have something like kor8, enu8, eng8, etc.

Vitaliy Serdtsev · Apr 24, 2025 go to post

It seems that adding to favorites via the management portal itself has also stopped working. Interestingly, there is no error in this case.

Add to favorites in Management Portal

Vitaliy Serdtsev · Apr 18, 2025 go to post

IRIS 2025.1.CE: the error is the same.

Why the %Library.EntityProjectionUtil class is missing in the system is a good question for developers.

Vitaliy Serdtsev · Apr 18, 2025 go to post

Script Command Arguments:

Note:

Any ASCII (extended) character except NUL (000) can be produced via <ddd> where ddd is the decimal value of the character.

USER>w $a("<")
60
USER>w $a(">")
62

So, something similar is needed:

echo: off
send: s V=4 I (V<60>48!(V<62>57))&&(V<60>65!(V<62>90))&&(V<60>97!(V<62>122))  W A,?10,G,?30,B,!
wait for:USER>

Vitaliy Serdtsev · Apr 15, 2025 go to post

I join the question @Ashok.Kumar.

I did not find DP-422635 and DP-424156 among the published ones:

In addition, there are no warnings in the documentation that these methods are deprecated and no longer work: Calling Functions and Procedures from Python

Vitaliy Serdtsev · Mar 31, 2025 go to post

Initially, the question was asked in relation to Caché or/and Ensemble 2018.1, but not to IRIS.