experience on creating instances in scotty-2.0.2 agent (repost)

Robert Premuz (rpremuz@srce.hr)
Sat, 23 Mar 1996 11:02:45 +0100 (MET)

Hello,

In this message, I'm going to express my experience on creating
instances by the `snmp# instance _label_ _varName_ [_default_]'
command.

First, a few words about creating instances.

On Sat, 9 Mar 1996, Buz Owen wrote in the 'snmp agent(s)' thread:

> Lest anyone is wondering, I tried this and it didn't make any
> difference. All sessions end up sharing (for any given mib
> variable) the instance binding to the last tcl variable, in its
> own namespace, as set by the last snmp instance command to
> reference that mib variable.

The scotty's source code in the scotty-2.0.2/snmp/snmpInst.c file
tells me that there is only one instance tree. (That tree actually
consists of all the nodes in the paths of all instances, and only some
of them hold instances.) The creation of an instance goes as follows:

If the instance does not already exist, additional nodes are created
in the instance tree and the info about the instance are set in the
structure of the corresponding node. Among other things, the structure
contains a pointer to the global Tcl variable which holds the value of
the instance. The name of the variable is given by the _varName_
argument of the 'snmp# instance' command. The name is taken literally
which means that the variable does not even need to be visible in the
context of the current procedure and, on the other hand, that a Tcl
variable defined by upvar command cannot be used. If the default value
is given by the _default_ argument, then the global variable is set to
that value.

If the instance does already exist, then only the info in the existing
node structure of the instance are appropriately changed.

All mentioned explains why an instance cannot be doubled in different
sessions by using different global variables, even if the variables
are from different name spaces. An instance is always bound to the
global variable given in the last 'snmp# instance' command regarding
that instance.

And how are instances removed? Well, at creation of an instance, an
unset trace for the _varName_ global variable is also created. The
trace procedure removes the instance when the global variable is
unset.

The main point of the message is, in fact, my little research on the
speed of creating instances.

When a lot of instances are created at once, for example while
updating a conceptual table holding a few thousands of variables in
its rows and columns, it is important that the creation of instances
is as fast as possible. To measure a few different possibilities in
using 'snmp# instance' command, I wrote the small agent script given
at the end of the message. If you run it, it will show you that:

using the OID of an instance for defining the instance to be created
(in the _label_ argument of the 'snmp# instance' command) is much more
efficient, than using the object descriptors (textual names) from a
MIB module.

The reason for that is probably the slow search through the MIB
information.

Also, when updating a possibly existing instance, it is more efficient
to check first if the global variable bound to the instance already
exists, and then to create the instance only if the variable does not
exist. If the variable already exists, then it only needs to be set to
the new value of the instance. Such checking is faster than the search
through the instance tree done by the 'snmp# instance' command when
updating an existing instance.

Some of the conclusions of this research could be put in the scotty
documentation so that the unexperienced writers of scotty agents do
not need to discover all that themselves.

What do you think about all that? Looking forward to your replies.

v
-- rpr. : Robert B. Premuz
Internet: rpremuz@malik.srce.hr * Voice at home: +385 (0)1 687564

--------------------------------------------------------------------------
#! /usr/local/bin/scotty -f
#
# an agent based on scotty 2.0.2 for testing the speed of creating
# instances of MIB objects

snmp alias sessOpts {-port 12345 -agent ""}
set agent [snmp session -alias sessOpts -version SNMPv2C]

mib load unix.mib

set nInst 100
set nRepeats 10

puts "Loop1: An instance is created using object descriptor (textual name)."
set timeTicks1 [time {
for {set i 0} {$i < $nInst} {incr i} {
$agent instance fsIdentifier.$i _fsTable(fsIdentifier.$i) $i
}
} $nRepeats]"

puts "Loop2: An instance is created using OID."
set oid(fsIdentifier) [mib oid fsIdentifier]
set timeTicks2 [time {
for {set i 0} {$i < $nInst} {incr i} {
$agent instance $oid(fsIdentifier).$i _fsTable(fsIdentifier.$i) $i
}
} $nRepeats]"

puts "Loop3:\
An instance is created using OID only if it does not already exist."
set timeTicks3 [time {
for {set i 0} {$i < $nInst} {incr i} {
if [info exists _fsTable(fsIdentifier.$i)] {
set _fsTable(fsIdentifier.$i) $i
} else {
$agent instance $oid(fsIdentifier).$i _fsTable(fsIdentifier.$i) $i
}
}
} $nRepeats]"

puts "Loop4: An instance is created using OID and then destroyed."
set oid(fsID) [mib oid fsIdentifier]
set timeTicks4 [time {
for {set i 0} {$i < $nInst} {incr i} {
$agent instance $oid(fsIdentifier).$i _fsTable(fsIdentifier.$i) $i
}
unset _fsTable
} $nRepeats]"

set speed1 [expr [lindex $timeTicks1 0] / $nInst]
set speed2 [expr [lindex $timeTicks2 0] / $nInst]
set speed3 [expr [lindex $timeTicks3 0] / $nInst]
set speed4 [expr [lindex $timeTicks4 0] / $nInst]

puts "speed1: $speed1 microseconds per MIB variable"
puts "speed2: $speed2 microseconds per MIB variable"
puts "speed3: $speed3 microseconds per MIB variable"
puts "speed4: $speed4 microseconds per MIB variable"

puts "speed1/speed2: [expr $speed1/$speed2]"
puts "speed1/speed3: [expr $speed1/$speed3]"
puts "speed1/speed4: [expr $speed1/$speed4]"
exit
--------------------------------------------------------------------------