Loading...
Searching...
No Matches
C# something changed
Date
26 dez 2024 - update to add new thread-pool features
11 dez 2024 - setup of the initial document

INDEX

I have to admit, I like C#

INDEX

Many things that are hard to do in another language are easy to do in C#. Integrating MONO into the NHI1-build-environment was child's play and otherwise I can only report positive things.

  • microsoft's documentation is exemplary and has left no question unanswered.
  • MONO is mature, has a lot of features and is supported by microsoft.
  • MONO integrate very well into the UNIX os and commandline.

Now I unfortunately have to report that MONO has been sold to microsoft, which would be completely legitimate if MONO still existed.

  • OpenSUSE has already not integrated the latest MONO packages.
  • microsoft itself has announced that .NET is now the actual distribution and MONO is hardly maintained anymore.

The biggest difference between MONO and .NET is the build environment, which is completely different, which logically also has a consequence with the integration into the NHI1-build-environment.

There are two basic types of build environments :

  1. An active environment that aims to offer a holistic solution that does not aim to integrate into an external solution and thus maximizes the integration wall :
  2. A passive environment that aims to integrate into an external solution and thus minimizes the integration wall :

Since, as described :

  • I am very satisfied with MONO, I have postponed the .NET integration for the time being.

THREADS

INDEX - HOWTO thread in PLMK

A thread is always a problem for so-called "high-level languages", i.e. everything outside of C and C++.

  • C# with MONO was an exception in this regard, especially under the version 6.8.0 supported by OpenSUSE.

Now MONO has been sold to microsoft, which initially favors a switch to their C# implementation .NET.

  • MONO with the current version 6.13.0 is still supported, but rather hesitantly

To make a long story short:

  • The thread support for OpenSUSE mono-6.8.0 is good and met my expectations.
  • The thread support for the current mono-6.13.0 is bad and falls behind in the mass test.
    • With C# thread support the application freezes in the middle of operation after a few hundred thread's.
    • With LINUX external thread support, the thread is unuseable in C#.

summary:

  1. Under LINUX with mono-6.8.0 the thread is good, but it is no longer supported.
  2. Under LINUX with mono-6-13.0 the thread support is unusable.
  3. I can't say whether it will be better with .NET because I haven't tested it.

THREAD POOL

INDEX - HOWTO Thread Pool

Example: CS thread pool using MqSysServerThreadF interface
namespace csmqmsgque {
public static partial class MqMsgque {
static unsafe private void MqSetupTmpl() {
Mq.MqSetup();
Mq.MqCsInit(MqSysServerThreadCB,MkSysExitCB);
}
private unsafe static MkErrorE MqSysServerThreadCB (
MkErrorE
IntPtr mkrt, IntPtr ctx, IntPtr argP, String name, int state, MkIdS *idP
) {
try {
var thread = Task.Factory.StartNew( () => {
Mq.MqSysServerThreadMain(argP);
});
(*idP).type = MkIdSE.THREAD;
if ((*idP).ioIsPipe) {
(*idP).val = (IntPtr)GCHandle.Alloc(thread,GCHandleType.Weak);
} else {
(*idP).val = (IntPtr) 0x1;
}
} catch (Exception ex) {
return MkErrorC.FORMAT().Catch(ex).GetCode();
}
return MkErrorE.OK;
MkIdSE
}
private static void MkSysExitCB ( int isThread, int num ) {
if (isThread != 0) {
// do nothing, end of MqSysServerThreadMain finish thread
} else {
Environment.Exit(num);
}
// FINISH
}
Example: CS context setup
namespace csmqmsgque {
// USER DEFINED CONFIG
public partial class MqContextC
{
// START class config
static MqContextC() {
// START type config
IntPtr ident_cstr = Marshal.StringToHGlobalAnsi("csmqmsgque_MqContextC");
unsafe {
MqContextCTT = Mq.MqCsContextTypeCreate(mkrt, ident_cstr,
fDefaultLinkCreate, null, fDefaultLinkCreate, null,
ProcessExit, ThreadExit, WaitForPipe);
}
Marshal.FreeHGlobal(ident_cstr);
// END type config
#define MqContextCTT
// END class config
}
private static void ProcessExit (IntPtr mkrt, int num) {
Environment.Exit (num);
}
private static void ThreadExit (IntPtr mkrt, int num) {
}
private unsafe static void WaitForPipe ( IntPtr mkrt, IntPtr ctx, MkIdS *idP ) {
switch ((*idP).type) {
case MkIdSE.PROCESS: {
// attention: theKernel/c/sys_mk.c -> SysWaitForProcess -> MK_ID_PROCESS
var p = Process.GetProcessById((*idP).val.ToInt32());
p.WaitForExit(200);
break;
}
case MkIdSE.THREAD: {
var hdl = GCHandle.FromIntPtr((*idP).val);
var task = (Task) hdl.Target;
if (task != null) {
task.Wait();
}
hdl.Free();
break;
}
case MkIdSE.UNUSED: {
break;
}
}
}

REFERENCES

INDEX - HOWTO Weak or Strong Reference

In Programming-Language-Micro-Kernel (PLMK), the connection to a language such as C# is regulated by a reference.

The pointer of a C# object is stored as week or strong reference :

weak
A weak reference is a reference that is still owned by the garbage-collection and is released there when necessary.
  • The self reference in MkObjectS::self only serves as a hint that there might be an object in the target language that resolves to NULL if necessary.
A weak reference is:
  • created with: IntPtr GCHandle.Alloc(this,GCHandleType.Weak)
  • resolved with object? GCHandle.FromIntPtr(self).Target (null return possible)
  • released with: GCHandle.FromIntPtr(self).Free()
strong
A strong reference is a reference that is owned by the Programming-Language-Micro-Kernel (PLMK) and is not released by the garbage-collection. A strong reference is:
  • created with: IntPtr GCHandle.Alloc(this)
  • resolved with object GCHandle.FromIntPtr(self).Target (null return not possible)
  • released with: GCHandle.FromIntPtr(self).Free()
A strong reference is a source for a memory-leak because every object not released by the Programming-Language-Micro-Kernel (PLMK) is also not released by the garbage-collection.
PLMK is able to deal with a weak or a strong reference.
By default the weak reference is used, a strong reference is activated with the compile-switch META_STRONG_REF

PERFORMANCE

INDEX - README_PERFORMANCE

I only compare the performance of C# with the performance of Java as a direct competitor.

call an empty callback from C

INDEX - perftests: --send-nothing

CS code
private void NTHT () {
}
CS result
 call: 'NHI1_HOME/performance/performance.bash' 'pr' '--send-nothing' '--sec' '4' '_pipe'


setup=perf-release
  > feature=cc_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ .../perf-release/inst/sbin/cc/x86_64-suse-linux-gnu-perfserver
      C> {x86_64-suse-linux-gnu-perfclient:pid(25468):tid(0x7f6c027a12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6c0278c440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25468):tid(0x7f6c027a12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6c0278c440):statistics                    }:                 --send-nothing :   535975.8 [  2144169 / 4.000496   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25468):tid(0x7f6c027a12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6c0278c440):PerfClientExec                }: end: ----------------------------------------
  > feature=c_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfserver
      C> {x86_64-suse-linux-gnu-perfclient:pid(25484):tid(0x7f9b869c62c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f9b869b1440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25484):tid(0x7f9b869c62c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f9b869b1440):statistics                    }:                 --send-nothing :   543397.0 [  2173706 / 4.000217   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25484):tid(0x7f9b869c62c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f9b869b1440):PerfClientExec                }: end: ----------------------------------------
  > feature=cs_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ /usr/bin/mono .../perf-release/inst/share/NHI1/perfserver.exe
      C> {x86_64-suse-linux-gnu-perfclient:pid(25501):tid(0x7fc1251932c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fc12517e440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25501):tid(0x7fc1251932c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fc12517e440):statistics                    }:                 --send-nothing :   429123.1 [  1716758 / 4.000619   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25501):tid(0x7fc1251932c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fc12517e440):PerfClientExec                }: end: ----------------------------------------
  > feature=jv_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ /usr/bin/java -jar .../perf-release/inst/share/NHI1/perfserver.jar
      C> {x86_64-suse-linux-gnu-perfclient:pid(25520):tid(0x7f554c7812c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f554c76c440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25520):tid(0x7f554c7812c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f554c76c440):statistics                    }:                 --send-nothing :   472206.4 [  1888940 / 4.000242   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25520):tid(0x7f554c7812c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f554c76c440):PerfClientExec                }: end: ----------------------------------------
  > feature=py_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/python3 .../perf-release/inst/sbin/py/x86_64-suse-linux-gnu-perfserver.py
      C> {x86_64-suse-linux-gnu-perfclient:pid(25556):tid(0x7f778c57b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f778c566440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25556):tid(0x7f778c57b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f778c566440):statistics                    }:                 --send-nothing :   499006.3 [  1996153 / 4.000256   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25556):tid(0x7f778c57b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f778c566440):PerfClientExec                }: end: ----------------------------------------
  > feature=rb_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/ruby .../perf-release/inst/sbin/rb/x86_64-suse-linux-gnu-perfserver.rb
      C> {x86_64-suse-linux-gnu-perfclient:pid(25575):tid(0x7f6a98ed12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6a98ebc440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25575):tid(0x7f6a98ed12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6a98ebc440):statistics                    }:                 --send-nothing :   471033.9 [  1884287 / 4.000321   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25575):tid(0x7f6a98ed12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f6a98ebc440):PerfClientExec                }: end: ----------------------------------------
  > feature=tcl_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --send-nothing --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/tclsh8.6 .../perf-release/inst/sbin/tcl/x86_64-suse-linux-gnu-perfserver.tcl
      C> {x86_64-suse-linux-gnu-perfclient:pid(25593):tid(0x7f516b7f02c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f516b7db440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25593):tid(0x7f516b7f02c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f516b7db440):statistics                    }:                 --send-nothing :   414436.1 [  1657972 / 4.000549   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25593):tid(0x7f516b7f02c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f516b7db440):PerfClientExec                }: end: ----------------------------------------
 
analysis
  1. Java code is 5% faster
  2. C# and Java ar now slower than open-source C, C++ and Python
  3. C# is on the level as TCL
  4. The reason why Java is 5% faster than C# is the API connection. Java has a C connection and C# does not.
  5. The C# profiler check:
    > Nhi1Exec -r=uds --extra-args='--profile=log:calls'  perfserver.cs
    > Nhi1Exec -r=uds                                     perfclient.c
    
    • create the results:
      ...
      Method call summary
      Total(ms) Self(ms)      Calls Method name
      ...
      Method call summary
      Total(ms) Self(ms)      Calls Method name
          1556      132     155628 (wrapper native-to-managed) csmqmsgque.MqContextC:ServiceCall (intptr,intptr,intptr)
          1423      303     155628 csmqmsgque.MqContextC:ServiceCall (intptr,intptr,intptr)
           626       95     155653 System.Runtime.InteropServices.GCHandle:FromIntPtr (intptr)
           530      244     155653 System.Runtime.InteropServices.GCHandle:op_Explicit (intptr)
           258      147     155637 System.Runtime.InteropServices.GCHandle:get_Target ()
           143       95     155653 System.Runtime.InteropServices.GCHandle:.ctor (intptr)
           138       92     155628 csmkkernel.Mk:CsRuntimeGetErrorCode (intptr)
            91       91     311306 intptr:op_Explicit (intptr)
            90       90     311355 intptr:op_Equality (intptr,intptr)
            63       63     155637 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:GetTarget (int)
            53       53     155653 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:CheckCurrentDomain (int)
            50       50     155626 example.perfserver:NTHT ()
            46       46     155637 System.Runtime.InteropServices.GCHandle:get_IsAllocated ()
            45       45     155638 intptr:ToPointer ()
      -------------------------------------------------------
      SUM          1546     >=155628
      ...
      
    • Only the values with calls >= 155628 count for the performance comparison and there it can be seen that the three calls that represent the native implementation:
          1556      132     155628 (wrapper native-to-managed) csmqmsgque.MqContextC:ServiceCall (intptr,intptr,intptr)
            63       63     155637 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:GetTarget (int)
            53       53     155653 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:CheckCurrentDomain (int)
      
    • are responsible for ~10% of the load and the actual "work":
            50       50     155626 example.perfserver:NTHT ()
      
    • only takes ~3% of the processing time.

call an MkBufferListC callback from C

INDEX - perftest: --bfl

CS code
private void BFLT () {
var bfl = MkBufferListC.CreateTLS( "perfserver-BFLT" );
while (ReadItemExists()) {
bfl.AppendBUF(ReadBUF());
}
SendSTART();
var size = bfl.Size();
for (int i=0; i<size; i++) {
SendBUF(bfl.IndexGet(i));
};
SendRETURN();
}
  • In the entire test cycle, no new objects are created. MkBufferListCreateTLS creates the MkBufferListC as thread-local and always returns the pale object with the identifier "perfserver-BFLT".
  • This applies not only to the bfl but also to the MkBufferC contained therein, which are retrieved with MkBufferListIndexGet.
CS result
 call: 'NHI1_HOME/performance/performance.bash' 'pr' '--bfl' '--sec' '4' '_pipe'


setup=perf-release
  > feature=cc_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ .../perf-release/inst/sbin/cc/x86_64-suse-linux-gnu-perfserver
      C> {x86_64-suse-linux-gnu-perfclient:pid(25656):tid(0x7f47b64432c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f47b642e440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25656):tid(0x7f47b64432c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f47b642e440):statistics                    }:                          --bfl :    73475.1 [   293901 / 4.000010   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25656):tid(0x7f47b64432c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f47b642e440):PerfClientExec                }: end: ----------------------------------------
  > feature=c_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfserver
      C> {x86_64-suse-linux-gnu-perfclient:pid(25671):tid(0x7f88486352c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8848620440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25671):tid(0x7f88486352c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8848620440):statistics                    }:                          --bfl :    86672.4 [   346690 / 4.000003   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25671):tid(0x7f88486352c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8848620440):PerfClientExec                }: end: ----------------------------------------
  > feature=cs_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ /usr/bin/mono .../perf-release/inst/share/NHI1/perfserver.exe
      C> {x86_64-suse-linux-gnu-perfclient:pid(25688):tid(0x7f515e38d2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f515e378440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25688):tid(0x7f515e38d2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f515e378440):statistics                    }:                          --bfl :    59200.3 [   236802 / 4.000014   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25688):tid(0x7f515e38d2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f515e378440):PerfClientExec                }: end: ----------------------------------------
  > feature=jv_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ /usr/bin/java -jar .../perf-release/inst/share/NHI1/perfserver.jar
      C> {x86_64-suse-linux-gnu-perfclient:pid(25707):tid(0x7fac513c12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fac513ac440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25707):tid(0x7fac513c12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fac513ac440):statistics                    }:                          --bfl :    72401.4 [   289606 / 4.000003   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25707):tid(0x7fac513c12c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fac513ac440):PerfClientExec                }: end: ----------------------------------------
  > feature=py_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/python3 .../perf-release/inst/sbin/py/x86_64-suse-linux-gnu-perfserver.py
      C> {x86_64-suse-linux-gnu-perfclient:pid(25742):tid(0x7f56411152c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f5641100440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25742):tid(0x7f56411152c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f5641100440):statistics                    }:                          --bfl :    64534.5 [   258138 / 4.000003   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25742):tid(0x7f56411152c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f5641100440):PerfClientExec                }: end: ----------------------------------------
  > feature=rb_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/ruby .../perf-release/inst/sbin/rb/x86_64-suse-linux-gnu-perfserver.rb
      C> {x86_64-suse-linux-gnu-perfclient:pid(25759):tid(0x7f09c72062c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f09c71f1440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25759):tid(0x7f09c72062c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f09c71f1440):statistics                    }:                          --bfl :    66952.9 [   267812 / 4.000003   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25759):tid(0x7f09c72062c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f09c71f1440):PerfClientExec                }: end: ----------------------------------------
  > feature=tcl_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --bfl --sec 4 @ /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/tclsh8.6 .../perf-release/inst/sbin/tcl/x86_64-suse-linux-gnu-perfserver.tcl
      C> {x86_64-suse-linux-gnu-perfclient:pid(25777):tid(0x7f2e9d33b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f2e9d326440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25777):tid(0x7f2e9d33b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f2e9d326440):statistics                    }:                          --bfl :    45807.1 [   183229 / 4.000013   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25777):tid(0x7f2e9d33b2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f2e9d326440):PerfClientExec                }: end: ----------------------------------------
 
analysis
  1. C# is significantly slower than its competitors, special Java is ~20% faster than C#
  2. The C# profiler check:
    > Nhi1Exec -r=uds --extra-args='--profile=log:calls'  perfserver.cs
    > Nhi1Exec -r=uds                                     perfclient.c
    
    • create the results:
      Method call summary
      Total(ms) Self(ms)      Calls Method name
          1830        7       7023 (wrapper native-to-managed) csmqmsgque.MqContextC:ServiceCall (intptr,intptr,intptr)
          1823       15       7023 csmqmsgque.MqContextC:ServiceCall (intptr,intptr,intptr)
          1755       69       7021 example.perfserver:BFLT ()
           704       63      70211 csmkkernel.MkBufferC:MkBufferC_ObjNew (intptr)
           685      118      77240 csmkkernel.MkObjectC:atomObjNew (System.Type,System.Reflection.ConstructorInfo,intptr)
           525       75      35106 csmqmsgque.MqContextC:ReadBUF ()
           523       75      35105 csmkkernel.MkBufferListC:IndexGet (int)
           332       51      84273 System.Runtime.InteropServices.GCHandle:FromIntPtr (intptr)
           285      189     323015 csmkkernel.MkObjectC:get_hdl ()
           280      125      84273 System.Runtime.InteropServices.GCHandle:op_Explicit (intptr)
           204       73      35106 csmqmsgque.MqContextC:SendBUF (csmkkernel.MkBufferC)
           166      166     561783 intptr:op_Equality (intptr,intptr)
           143       53      35105 csmkkernel.MkBufferListC:AppendBUF (csmkkernel.MkBufferC)
           135       77      84257 System.Runtime.InteropServices.GCHandle:get_Target ()
           114       68      77242 csmkkernel.Mk:CsGetSelfPtr (intptr)
           100       11       7021 csmkkernel.MkBufferListC:CreateTLS (string,bool)
            91       37      42126 csmqmsgque.MqContextC:ReadItemExists ()
            75       49      84273 System.Runtime.InteropServices.GCHandle:.ctor (intptr)
            70        6       7021 csmkkernel.MkBufferListC:MkBufferListC_ObjNew (intptr)
            62       41      70212 csmkkernel.MkObjectC:getOBJ (string,csmkkernel.MkObjectC)
            52       52     168546 intptr:op_Explicit (intptr)
            48       48     161530 csmkkernel.MkObjectC:get_mkrt ()
            46       46     154488 intptr:op_Inequality (intptr,intptr)
            45       13       7022 csmqmsgque.MqContextC:SendRETURN ()
            44       35     119376 csmkkernel.MkErrorC:Check (intptr,csmkkernel.MkErrorE)
            33       12       7022 csmqmsgque.MqContextC:SendSTART ()
            32       32      84257 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:GetTarget (int)
            28       28      84273 (wrapper managed-to-native) System.Runtime.InteropServices.GCHandle:CheckCurrentDomain (int)
            25       25      84264 intptr:ToPointer ()
            25       25      84257 System.Runtime.InteropServices.GCHandle:get_IsAllocated ()
            20        8       7021 csmkkernel.MkBufferListC:Size ()
            16       16      42126 (wrapper managed-to-native) csmqmsgque.Mq:MqReadItemExists (intptr)
            16       16      35105 (wrapper managed-to-native) csmkkernel.Mk:MkBufferListAppendBUF (intptr,intptr,intptr)
            15       15       7022 (wrapper managed-to-native) csmqmsgque.Mq:MqSendRETURN (intptr,intptr)
            15       15      35106 (wrapper managed-to-native) csmqmsgque.Mq:MqSendBUF (intptr,intptr,intptr)
            15       15      35106 (wrapper managed-to-native) csmqmsgque.Mq:MqReadBUF (intptr,intptr,intptr&)
            14       14      35105 (wrapper managed-to-native) csmkkernel.Mk:MkBufferListIndexGet (intptr,intptr,int,intptr&)
            10        4       7053 System.Runtime.InteropServices.Marshal:StringToHGlobalAnsi (string)
      
    • no significant reason for the C# overhead

compare CS versa JV in pipe mode

INDEX - README_PERFORMANCE

results
 call: 'NHI1_HOME/performance/performance.bash' 'pr' '--all-performance' '--sec' '4' '^(cs|jv)_pipe'


setup=perf-release
  > feature=cs_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --all-performance --sec 4 @ /usr/bin/mono .../perf-release/inst/share/NHI1/perfserver.exe
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                 --send-nothing :   443287.0 [  1773225 / 4.000174   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                         --send :   271675.3 [  1086758 / 4.000210   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:            --send-and-callback :   154799.1 [   619379 / 4.001178   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                --send-and-wait :    74855.9 [   299424 / 4.000005   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                       --parent :       21.7 [       87 / 4.009635   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                        --child :    16513.6 [    66055 / 4.000048   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                          --bus :    57408.0 [   229633 / 4.000018   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):statistics                    }:                          --bfl :    60758.7 [   243035 / 4.000000   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(25860):tid(0x7f83524872c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f8352472440):PerfClientExec                }: end: ----------------------------------------
    > mv 'NHI1_BUILD/performance/temp.perf.perf-release.cs_pipe' 'NHI1_HOME/performance/gen/x86_64-suse-linux-gnu/perf-release/cs_pipe.perf'
  > feature=jv_pipe
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --all-performance --sec 4 @ /usr/bin/java -jar .../perf-release/inst/share/NHI1/perfserver.jar
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                 --send-nothing :   476037.0 [  1904387 / 4.000502   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                         --send :   298682.3 [  1194774 / 4.000150   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:            --send-and-callback :   164119.9 [   656634 / 4.000942   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                --send-and-wait :    78644.3 [   314578 / 4.000011   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                       --parent :       21.2 [       85 / 4.000181   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                        --child :    19651.8 [    78608 / 4.000040   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                          --bus :    70445.0 [   281780 / 4.000002   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):statistics                    }:                          --bfl :    71173.7 [   284695 / 4.000002   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(26147):tid(0x7fa5393a52c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fa539390440):PerfClientExec                }: end: ----------------------------------------
    > mv 'NHI1_BUILD/performance/temp.perf.perf-release.jv_pipe' 'NHI1_HOME/performance/gen/x86_64-suse-linux-gnu/perf-release/jv_pipe.perf'
 
analysis
  1. Java is clearly faster than C#, only in process-startup C# is a little faster but in the end this hardly makes a difference.

compare parent versa child startup in thread mode

INDEX - README_PERFORMANCE

results
 call: 'NHI1_HOME/performance/performance.bash' 'pr' '--parent' '--child' '--sec' '4' '_uds_thread'


setup=perf-release
  > feature=cc_uds_thread
    > .../perf-release/inst/sbin/cc/x86_64-suse-linux-gnu-perfserver --uds --file ./socket.uds.0 --thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --parent --child --sec 4 --uds --file ./socket.uds.0
      C> {x86_64-suse-linux-gnu-perfclient:pid(28188):tid(0x7f4adc5902c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4adc57b440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(28188):tid(0x7f4adc5902c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4adc57b440):statistics                    }:                       --parent :    10330.5 [    41324 / 4.000177   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(28188):tid(0x7f4adc5902c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4adc57b440):statistics                    }:                        --child :    36505.2 [   146021 / 4.000001   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(28188):tid(0x7f4adc5902c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4adc57b440):PerfClientExec                }: end: ----------------------------------------
  > feature=cs_uds_thread
    > /usr/bin/mono .../perf-release/inst/share/NHI1/perfserver.exe --uds --file ./socket.uds.1 --thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --parent --child --sec 4 --uds --file ./socket.uds.1
      C> {x86_64-suse-linux-gnu-perfclient:pid(69575):tid(0x7f4ef20762c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4ef2061440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69575):tid(0x7f4ef20762c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4ef2061440):statistics                    }:                       --parent :    11054.7 [    44220 / 4.000118   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69575):tid(0x7f4ef20762c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4ef2061440):statistics                    }:                        --child :    21754.1 [    87017 / 4.000028   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69575):tid(0x7f4ef20762c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f4ef2061440):PerfClientExec                }: end: ----------------------------------------
  > feature=c_uds_thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfserver --uds --file ./socket.uds.2 --thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --parent --child --sec 4 --uds --file ./socket.uds.2
      C> {x86_64-suse-linux-gnu-perfclient:pid(69613):tid(0x7fb03340f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fb0333fa440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69613):tid(0x7fb03340f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fb0333fa440):statistics                    }:                       --parent :    12347.8 [    49393 / 4.000144   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69613):tid(0x7fb03340f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fb0333fa440):statistics                    }:                        --child :    37620.2 [   150481 / 4.000005   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(69613):tid(0x7fb03340f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7fb0333fa440):PerfClientExec                }: end: ----------------------------------------
  > feature=jv_uds_thread
    > /usr/bin/java -jar .../perf-release/inst/share/NHI1/perfserver.jar --uds --file ./socket.uds.3 --thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --parent --child --sec 4 --uds --file ./socket.uds.3
      C> {x86_64-suse-linux-gnu-perfclient:pid(46228):tid(0x7f78085882c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f7808573440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46228):tid(0x7f78085882c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f7808573440):statistics                    }:                       --parent :    13961.1 [    55846 / 4.000111   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46228):tid(0x7f78085882c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f7808573440):statistics                    }:                        --child :    19807.1 [    79229 / 4.000040   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46228):tid(0x7f78085882c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f7808573440):PerfClientExec                }: end: ----------------------------------------
  > feature=tcl_uds_thread
    > /home/dev1usr/ext/x86_64-suse-linux-gnu/release/bin/tclsh8.6 .../perf-release/inst/sbin/tcl/x86_64-suse-linux-gnu-perfserver.tcl --uds --file ./socket.uds.4 --thread
    > .../perf-release/inst/sbin/c/x86_64-suse-linux-gnu-perfclient --timeout 2 --parent --child --sec 4 --uds --file ./socket.uds.4
      C> {x86_64-suse-linux-gnu-perfclient:pid(46269):tid(0x7f726410f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f72640fa440):PerfClientExec                }: start ------------------------ :     result [    count / sec        ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46269):tid(0x7f726410f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f72640fa440):statistics                    }:                       --parent :       38.5 [      154 / 4.000189   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46269):tid(0x7f726410f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f72640fa440):statistics                    }:                        --child :    23844.6 [    95379 / 4.000020   ]
      C> {x86_64-suse-linux-gnu-perfclient:pid(46269):tid(0x7f726410f2c0):L:dlv(0):ctxId( 0):rc(0):ctx(0x7f72640fa440):PerfClientExec                }: end: ----------------------------------------
 
analysis
  1. The values were determined for a single processor (–wrk 1) environment.
  2. The real performance can be multiplied by the number of physical processors…
    • The maximum achievable number of new sessions (--parent) with thread startup and the new thread-pool functionality is limited by the time for creating a new context (--child).
    • A Xeon E3-1275 V2 with 4 physical processors can therefore process max 150,000 sessions per second.
      • calculation for a C application server: 4 processors x 37,000 ctx/sec = ~150,000 ctx/sec.
  3. C# is significant slower the Java in thread startup even if a thread-pool is used.