Index: gc_lang/fr/modules/tests_modules.py
==================================================================
--- gc_lang/fr/modules/tests_modules.py
+++ gc_lang/fr/modules/tests_modules.py
@@ -20,11 +20,11 @@
     start = time.perf_counter()
     try:
         yield
     finally:
         end = time.perf_counter()
-        print('{} : {}'.format(label, end - start))
+        print('{:<20} : {}'.format(label, end - start))
         if hDst:
             hDst.write("{:<12.6}".format(end-start))
 
 
 class TestDictionary (unittest.TestCase):
@@ -49,11 +49,11 @@
     def test_isvalid_failed (self):
         for sWord in ["BranchE", "BRanche", "BRAnCHE", "émilie", "éMILIE", "émiLie"]:
             self.assertFalse(self.oDic.isValid(sWord), sWord)
 
     def test_suggest (self):
-        for sWord in ["déelirranttesss", "vallidasion", "Emilie", "exibission"]:
+        for sWord in ["déelirranttesss", "vallidasion", "Emilie", "exibission", "ditirembique", "jai", "email"]:
             with timeblock(sWord):
                 self.assertNotEqual(0, self.oDic.suggest(sWord))
 
 
 class TestConjugation (unittest.TestCase):

Index: gc_lang/fr/perf_memo.text
==================================================================
--- gc_lang/fr/perf_memo.text
+++ gc_lang/fr/perf_memo.text
@@ -28,7 +28,8 @@
 1.1         2019.05.16 09:42    1.50743     0.360923    0.261113    0.0749272   0.0763827   0.0771537   0.180504    0.102942    0.0182762   0.0021925   (×2, but new processor: AMD Ryzen 7 2700X)
 1.2.1       2019.08.06 20:57    1.42886     0.358425    0.247356    0.0704405   0.0754886   0.0765604   0.177197    0.0988517   0.0188103   0.0020243
 1.6.0       2020.01.03 20:22    1.38847     0.346214    0.240242    0.0709539   0.0737499   0.0748733   0.176477    0.0969171   0.0187857   0.0025143   (nouveau dictionnaire avec lemmes masculins)
 1.9.0       2020.04.20 19:57    1.51183     0.369546    0.25681     0.0734314   0.0764396   0.0785668   0.183922    0.103674    0.0185812   0.002099    (NFC normalization)
 1.9.2       2020.05.12 08:43    1.62465     0.398831    0.273012    0.0810811   0.080937    0.0845885   0.204133    0.114146    0.0212864   0.0029547
-1.12.2      2020.09.09 13:34    1.50568     0.374504    0.233108    0.0798712   0.0804466   0.0769674   0.171519    0.0945132   0.0165344   0.0019474   
-1.12.2      2020.09.09 13:35    1.41094     0.359093    0.236443    0.06968     0.0734418   0.0738087   0.169371    0.0946279   0.0167106   0.0019773   
+1.12.2      2020.09.09 13:34    1.50568     0.374504    0.233108    0.0798712   0.0804466   0.0769674   0.171519    0.0945132   0.0165344   0.0019474
+1.12.2      2020.09.09 13:35    1.41094     0.359093    0.236443    0.06968     0.0734418   0.0738087   0.169371    0.0946279   0.0167106   0.0019773
+1.12.2      2020.09.11 19:16    1.35297     0.330545    0.221731    0.0666998   0.0692539   0.0701707   0.160564    0.0891676   0.015807    0.0045998

Index: graphspell-js/ibdawg.js
==================================================================
--- graphspell-js/ibdawg.js
+++ graphspell-js/ibdawg.js
@@ -122,24 +122,10 @@
             Properties:
             sName, nCompressionMethod, sHeader, lArcVal, nArcVal, sByDic, sLang, nChar, nBytesArc, nBytesNodeAddress,
             nEntry, nNode, nArc, nAff, cStemming, nTag, dChar, nBytesOffset,
         */
 
-        /*
-            Bug workaround.
-            Mozilla’s JS parser sucks. Can’t read file bigger than 4 Mb!
-            So we convert huge hexadecimal string to list of numbers…
-            https://github.com/mozilla/addons-linter/issues/1361
-        */
-        let lTemp = [];
-        for (let i = 0;  i < this.sByDic.length;  i+=2) {
-            lTemp.push(parseInt(this.sByDic.slice(i, i+2), 16));
-        }
-        this.byDic = lTemp;
-        //this.byDic = new Uint8Array(lTemp);  // not quicker, even slower
-        /* end of bug workaround */
-
         if (!(this.sHeader.startsWith("/grammalecte-fsa/") || this.sHeader.startsWith("/pyfsa/"))) {
             throw TypeError("# Error. Not a grammalecte-fsa binary dictionary. Header: " + this.sHeader);
         }
         if (!(this.nCompressionMethod == 1 || this.nCompressionMethod == 2 || this.nCompressionMethod == 3)) {
             throw RangeError("# Error. Unknown dictionary compression method: " + this.nCompressionMethod);
@@ -155,41 +141,45 @@
             this.funcStemming = str_transform.changeWordWithAffixCode;
         } else {
             this.funcStemming = str_transform.noStemming;
         }
 
+        /*
+            Bug workaround.
+            Mozilla’s JS parser sucks. Can’t read file bigger than 4 Mb!
+            So we convert huge hexadecimal string to list of numbers…
+            https://github.com/mozilla/addons-linter/issues/1361
+        */
+        /*
+            Performance trick:
+            Instead of converting bytes to integers each times we parse the binary dictionary,
+            we do it once, then parse the array
+        */
+        let nAcc = 0;
+        let lBytesBuffer = [];
+        let lTemp = [];
+        let nDivisor = (this.nBytesArc + this.nBytesNodeAddress) / 2;
+        for (let i = 0;  i < this.sByDic.length;  i+=2) {
+            lBytesBuffer.push(parseInt(this.sByDic.slice(i, i+2), 16));
+            if (nAcc == (this.nBytesArc - 1)) {
+                lTemp.push(this._convBytesToInteger(lBytesBuffer));
+                lBytesBuffer = [];
+            }
+            else if (nAcc == (this.nBytesArc + this.nBytesNodeAddress - 1)) {
+                lTemp.push(Math.round(this._convBytesToInteger(lBytesBuffer) / nDivisor));  // Math.round should be useless, BUT with JS who knowns what can happen…
+                lBytesBuffer = [];
+                nAcc = -1;
+            }
+            nAcc = nAcc + 1;
+        }
+        this.byDic = lTemp;
+        /* end of bug workaround */
+
         this._arcMask = (2 ** ((this.nBytesArc * 8) - 3)) - 1;
         this._finalNodeMask = 1 << ((this.nBytesArc * 8) - 1);
         this._lastArcMask = 1 << ((this.nBytesArc * 8) - 2);
 
-
-        // Configuring DAWG functions according to nCompressionMethod
-        switch (this.nCompressionMethod) {
-            case 1:
-                this.morph = this._morph1;
-                this.stem = this._stem1;
-                this._lookupArcNode = this._lookupArcNode1;
-                this._getArcs = this._getArcs1;
-                this._writeNodes = this._writeNodes1;
-                break;
-            case 2:
-                this.morph = this._morph2;
-                this.stem = this._stem2;
-                this._lookupArcNode = this._lookupArcNode2;
-                this._getArcs = this._getArcs2;
-                this._writeNodes = this._writeNodes2;
-                break;
-            case 3:
-                this.morph = this._morph3;
-                this.stem = this._stem3;
-                this._lookupArcNode = this._lookupArcNode3;
-                this._getArcs = this._getArcs3;
-                this._writeNodes = this._writeNodes3;
-                break;
-            default:
-                throw ValueError("# Error: unknown code: " + this.nCompressionMethod);
-        }
         //console.log(this.getInfo());
         this.bAcronymValid = true;
         this.bNumAtLastValid = false;
 
         // lexicographer module ?
@@ -196,11 +186,10 @@
         this.lexicographer = null;
         // JS still sucks: we’ll try importation when importation will be available in Workers. Still waiting...
         if (self && self.hasOwnProperty("lexgraph_"+this.sLangCode)) { // self is the Worker
             this.lexicographer = self["lexgraph_"+this.sLangCode];
         }
-
     }
 
     getInfo () {
         return  `  Language: ${this.sLangName}   Lang code: ${this.sLangCode}   Dictionary name: ${this.sDicName}\n` +
                 `  Compression method: ${this.nCompressionMethod}   Date: ${this.sDate}   Stemming: ${this.cStemming}FX\n` +
@@ -306,24 +295,24 @@
             iAddr = this._lookupArcNode(this.dChar.get(c), iAddr);
             if (iAddr === null) {
                 return false;
             }
         }
-        return Boolean(this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask);
+        return Boolean(this.byDic[iAddr] & this._finalNodeMask);
     }
 
     getMorph (sWord) {
         // retrieves morphologies list, different casing allowed
         if (!sWord) {
             return [];
         }
         sWord = str_transform.spellingNormalization(sWord);
-        let l = this.morph(sWord);
+        let l = this._morph(sWord);
         if (sWord[0].gl_isUpperCase()) {
-            l.push(...this.morph(sWord.toLowerCase()));
+            l.push(...this._morph(sWord.toLowerCase()));
             if (sWord.gl_isUpperCase() && sWord.length > 1) {
-                l.push(...this.morph(sWord.gl_toCapitalize()));
+                l.push(...this._morph(sWord.gl_toCapitalize()));
             }
         }
         return l;
     }
 
@@ -378,11 +367,11 @@
     }
 
     _suggest (oSuggResult, sRemain, nMaxSwitch=0, nMaxDel=0, nMaxHardRepl=0, nMaxJump=0, nDist=0, nDeep=0, iAddr=0, sNewWord="", bAvoidLoop=false) {
         // returns a set of suggestions
         // recursive function
-        if (this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask) {
+        if (this.byDic[iAddr] & this._finalNodeMask) {
             if (sRemain == "") {
                 oSuggResult.addSugg(sNewWord);
                 for (let sTail of this._getTails(iAddr)) {
                     oSuggResult.addSugg(sNewWord+sTail);
                 }
@@ -488,11 +477,11 @@
     _getTails (iAddr, sTail="", n=2) {
         // return a list of suffixes ending at a distance of <n> from <iAddr>
         let aTails = new Set();
         for (let [nVal, jAddr] of this._getArcs(iAddr)) {
             if (nVal <= this.nChar) {
-                if (this._convBytesToInteger(this.byDic.slice(jAddr, jAddr+this.nBytesArc)) & this._finalNodeMask) {
+                if (this.byDic[jAddr] & this._finalNodeMask) {
                     aTails.add(sTail + this.dCharVal.get(nVal));
                 }
                 if (n && aTails.size == 0) {
                     aTails.gl_update(this._getTails(jAddr, sTail+this.dCharVal.get(nVal), n-1));
                 }
@@ -530,35 +519,33 @@
         }
         catch (e) {
             console.log("Error in regex pattern");
             console.log(e.message);
         }
-        yield* this._select1(zFlexPattern, zTagsPattern, 0, "");
+        yield* this._select(zFlexPattern, zTagsPattern, 0, "");
     }
 
-    // VERSION 1
-
-    * _select1 (zFlexPattern, zTagsPattern, iAddr, sWord) {
+    * _select (zFlexPattern, zTagsPattern, iAddr, sWord) {
         // recursive generator
-        for (let [nVal, jAddr] of this._getArcs1(iAddr)) {
+        for (let [nVal, jAddr] of this._getArcs(iAddr)) {
             if (nVal <= this.nChar) {
                 // simple character
-                yield* this._select1(zFlexPattern, zTagsPattern, jAddr, sWord + this.lArcVal[nVal]);
+                yield* this._select(zFlexPattern, zTagsPattern, jAddr, sWord + this.lArcVal[nVal]);
             } else {
                 if (!zFlexPattern || zFlexPattern.test(sWord)) {
                     let sStem = this.funcStemming(sWord, this.lArcVal[nVal]);
-                    for (let [nMorphVal, _] of this._getArcs1(jAddr)) {
+                    for (let [nMorphVal, _] of this._getArcs(jAddr)) {
                         if (!zTagsPattern || zTagsPattern.test(this.lArcVal[nMorphVal])) {
                             yield [sWord, sStem, this.lArcVal[nMorphVal]];
                         }
                     }
                 }
             }
         }
     }
 
-    _morph1 (sWord) {
+    _morph (sWord) {
         // returns morphologies of sWord
         let iAddr = 0;
         for (let c of sWord) {
             if (!this.dChar.has(c)) {
                 return [];
@@ -566,38 +553,38 @@
             iAddr = this._lookupArcNode(this.dChar.get(c), iAddr);
             if (iAddr === null) {
                 return [];
             }
         }
-        if (this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask) {
+        if (this.byDic[iAddr] & this._finalNodeMask) {
             let l = [];
             let nRawArc = 0;
             while (!(nRawArc & this._lastArcMask)) {
-                let iEndArcAddr = iAddr + this.nBytesArc;
-                nRawArc = this._convBytesToInteger(this.byDic.slice(iAddr, iEndArcAddr));
+                let iEndArcAddr = iAddr + 1;
+                nRawArc = this.byDic[iAddr];
                 let nArc = nRawArc & this._arcMask;
                 if (nArc > this.nChar) {
                     // This value is not a char, this is a stemming code
                     let sStem = ">" + this.funcStemming(sWord, this.lArcVal[nArc]);
                     // Now , we go to the next node and retrieve all following arcs values, all of them are tags
-                    let iAddr2 = this._convBytesToInteger(this.byDic.slice(iEndArcAddr, iEndArcAddr+this.nBytesNodeAddress));
+                    let iAddr2 = this.byDic[iEndArcAddr];
                     let nRawArc2 = 0;
                     while (!(nRawArc2 & this._lastArcMask)) {
-                        let iEndArcAddr2 = iAddr2 + this.nBytesArc;
-                        nRawArc2 = this._convBytesToInteger(this.byDic.slice(iAddr2, iEndArcAddr2));
+                        let iEndArcAddr2 = iAddr2 + 1;
+                        nRawArc2 = this.byDic[iAddr2];
                         l.push(sStem + "/" + this.lArcVal[nRawArc2 & this._arcMask]);
-                        iAddr2 = iEndArcAddr2+this.nBytesNodeAddress;
+                        iAddr2 = iEndArcAddr2 + 1;
                     }
                 }
-                iAddr = iEndArcAddr + this.nBytesNodeAddress;
+                iAddr = iEndArcAddr + 1;
             }
             return l;
         }
         return [];
     }
 
-    _stem1 (sWord) {
+    _stem (sWord) {
         // returns stems list of sWord
         let iAddr = 0;
         for (let c of sWord) {
             if (!this.dChar.has(c)) {
                 return [];
@@ -605,88 +592,61 @@
             iAddr = this._lookupArcNode(this.dChar.get(c), iAddr);
             if (iAddr === null) {
                 return [];
             }
         }
-        if (this._convBytesToInteger(this.byDic.slice(iAddr, iAddr+this.nBytesArc)) & this._finalNodeMask) {
+        if (this.byDic[iAddr] & this._finalNodeMask) {
             let l = [];
             let nRawArc = 0;
             while (!(nRawArc & this._lastArcMask)) {
-                let iEndArcAddr = iAddr + this.nBytesArc;
-                nRawArc = this._convBytesToInteger(this.byDic.slice(iAddr, iEndArcAddr));
+                let iEndArcAddr = iAddr + 1;
+                nRawArc = this.byDic[iAddr];
                 let nArc = nRawArc & this._arcMask;
                 if (nArc > this.nChar) {
                     // This value is not a char, this is a stemming code
                     l.push(this.funcStemming(sWord, this.lArcVal[nArc]));
                 }
-                iAddr = iEndArcAddr + this.nBytesNodeAddress;
+                iAddr = iEndArcAddr + 1;
             }
             return l;
         }
         return [];
     }
 
-    _lookupArcNode1 (nVal, iAddr) {
+    _lookupArcNode (nVal, iAddr) {
         // looks if nVal is an arc at the node at iAddr, if yes, returns address of next node else None
         while (true) {
-            let iEndArcAddr = iAddr+this.nBytesArc;
-            let nRawArc = this._convBytesToInteger(this.byDic.slice(iAddr, iEndArcAddr));
+            let iEndArcAddr = iAddr+1;
+            let nRawArc = this.byDic[iAddr];
             if (nVal == (nRawArc & this._arcMask)) {
                 // the value we are looking for
                 // we return the address of the next node
-                return this._convBytesToInteger(this.byDic.slice(iEndArcAddr, iEndArcAddr+this.nBytesNodeAddress));
+                return this.byDic[iEndArcAddr];
             }
             else {
                 // value not found
                 if (nRawArc & this._lastArcMask) {
                     return null;
                 }
-                iAddr = iEndArcAddr + this.nBytesNodeAddress;
-            }
-        }
-    }
-
-    * _getArcs1 (iAddr) {
-        // generator: return all arcs at <iAddr> as tuples of (nVal, iAddr)
-        while (true) {
-            let iEndArcAddr = iAddr+this.nBytesArc;
-            let nRawArc = this._convBytesToInteger(this.byDic.slice(iAddr, iEndArcAddr));
-            yield [nRawArc & this._arcMask, this._convBytesToInteger(this.byDic.slice(iEndArcAddr, iEndArcAddr+this.nBytesNodeAddress))];
-            if (nRawArc & this._lastArcMask) {
-                break;
-            }
-            iAddr = iEndArcAddr+this.nBytesNodeAddress;
-        }
-    }
-
-    // VERSION 2
-    _morph2 (sWord) {
-        // to do
-    }
-
-    _stem2 (sWord) {
-        // to do
-    }
-
-    _lookupArcNode2 (nVal, iAddr) {
-        // to do
-    }
-
-
-    // VERSION 3
-    _morph3 (sWord) {
-        // to do
-    }
-
-    _stem3 (sWord) {
-        // to do
-    }
-
-    _lookupArcNode3 (nVal, iAddr) {
-        // to do
+                iAddr = iEndArcAddr + 1;
+            }
+        }
+    }
+
+    * _getArcs (iAddr) {
+        // generator: return all arcs at <iAddr> as tuples of (nVal, iAddr)
+        while (true) {
+            let iEndArcAddr = iAddr+1;
+            let nRawArc = this.byDic[iAddr];
+            yield [nRawArc & this._arcMask, this.byDic[iEndArcAddr]];
+            if (nRawArc & this._lastArcMask) {
+                break;
+            }
+            iAddr = iEndArcAddr+1;
+        }
     }
 }
 
 
 if (typeof(exports) !== 'undefined') {
     exports.IBDAWG = IBDAWG;
 }

Index: graphspell/ibdawg.py
==================================================================
--- graphspell/ibdawg.py
+++ graphspell/ibdawg.py
@@ -118,10 +118,30 @@
         else:
             self._initJSON(source)
 
         self.sFileName = source  if isinstance(source, str)  else "[None]"
 
+        # Performance trick:
+        #     Instead of converting bytes to integers each times we parse the binary dictionary,
+        #     we do it once, then parse the array
+        nAcc = 0
+        byBuffer = b""
+        lTemp = []
+        nDivisor = (self.nBytesArc + self.nBytesNodeAddress) / 2
+        for i in range(0, len(self.byDic)):
+            byBuffer += self.byDic[i:i+1]
+            if nAcc == (self.nBytesArc - 1):
+                lTemp.append(int.from_bytes(byBuffer, byteorder="big"))
+                byBuffer = b""
+            elif nAcc == (self.nBytesArc + self.nBytesNodeAddress - 1):
+                lTemp.append(round(int.from_bytes(byBuffer, byteorder="big") / nDivisor))
+                byBuffer = b""
+                nAcc = -1
+            nAcc = nAcc + 1
+        self.byDic = lTemp;
+
+        # masks
         self._arcMask = (2 ** ((self.nBytesArc * 8) - 3)) - 1
         self._finalNodeMask = 1 << ((self.nBytesArc * 8) - 1)
         self._lastArcMask = 1 << ((self.nBytesArc * 8) - 2)
         self._addrBitMask = 1 << ((self.nBytesArc * 8) - 3)  # version 2
 
@@ -298,11 +318,11 @@
             if c not in self.dChar:
                 return False
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
             if iAddr is None:
                 return False
-        return bool(int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask)
+        return bool(self.byDic[iAddr] & self._finalNodeMask)
 
     def getMorph (self, sWord):
         "retrieves morphologies list, different casing allowed"
         if not sWord:
             return []
@@ -354,11 +374,11 @@
                     oSuggResult.addSugg(sWord1+" "+sWord2)
 
     def _suggest (self, oSuggResult, sRemain, nMaxSwitch=0, nMaxDel=0, nMaxHardRepl=0, nMaxJump=0, nDist=0, nDeep=0, iAddr=0, sNewWord="", bAvoidLoop=False):
         # recursive function
         #logging.info((nDeep * "  ") + sNewWord + ":" + sRemain)
-        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
+        if self.byDic[iAddr] & self._finalNodeMask:
             if not sRemain:
                 oSuggResult.addSugg(sNewWord, nDeep)
                 for sTail in self._getTails(iAddr):
                     oSuggResult.addSugg(sNewWord+sTail, nDeep)
                 return
@@ -421,11 +441,11 @@
     def _getTails (self, iAddr, sTail="", n=2):
         "return a list of suffixes ending at a distance of <n> from <iAddr>"
         aTails = set()
         for nVal, jAddr in self._getArcs(iAddr):
             if nVal <= self.nChar:
-                if int.from_bytes(self.byDic[jAddr:jAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
+                if self.byDic[jAddr] & self._finalNodeMask:
                     aTails.add(sTail + self.dCharVal[nVal])
                 if n and not aTails:
                     aTails.update(self._getTails(jAddr, sTail+self.dCharVal[nVal], n-1))
         return aTails
 
@@ -497,29 +517,29 @@
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
             if iAddr is None:
                 return []
-        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
+        if self.byDic[iAddr] & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not nRawArc & self._lastArcMask:
-                iEndArcAddr = iAddr + self.nBytesArc
-                nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
+                iEndArcAddr = iAddr + 1
+                nRawArc = self.byDic[iAddr]
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
                     # This value is not a char, this is a stemming code
                     sStem = ">" + self.funcStemming(sWord, self.lArcVal[nArc])
                     # Now , we go to the next node and retrieve all following arcs values, all of them are tags
-                    iAddr2 = int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
+                    iAddr2 = self.byDic[iEndArcAddr]
                     nRawArc2 = 0
                     while not nRawArc2 & self._lastArcMask:
-                        iEndArcAddr2 = iAddr2 + self.nBytesArc
-                        nRawArc2 = int.from_bytes(self.byDic[iAddr2:iEndArcAddr2], byteorder='big')
+                        iEndArcAddr2 = iAddr2 + 1
+                        nRawArc2 = self.byDic[iAddr2]
                         l.append(sStem + "/" + self.lArcVal[nRawArc2 & self._arcMask])
-                        iAddr2 = iEndArcAddr2+self.nBytesNodeAddress
-                iAddr = iEndArcAddr+self.nBytesNodeAddress
+                        iAddr2 = iEndArcAddr2 + 1
+                iAddr = iEndArcAddr + 1
             return l
         return []
 
     def _stem1 (self, sWord):
         "returns stems list of <sWord>"
@@ -528,62 +548,60 @@
             if c not in self.dChar:
                 return []
             iAddr = self._lookupArcNode(self.dChar[c], iAddr)
             if iAddr is None:
                 return []
-        if int.from_bytes(self.byDic[iAddr:iAddr+self.nBytesArc], byteorder='big') & self._finalNodeMask:
+        if self.byDic[iAddr] & self._finalNodeMask:
             l = []
             nRawArc = 0
             while not nRawArc & self._lastArcMask:
-                iEndArcAddr = iAddr + self.nBytesArc
-                nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
+                iEndArcAddr = iAddr + 1
+                nRawArc = self.byDic[iAddr]
                 nArc = nRawArc & self._arcMask
                 if nArc > self.nChar:
                     # This value is not a char, this is a stemming code
                     l.append(self.funcStemming(sWord, self.lArcVal[nArc]))
-                iAddr = iEndArcAddr+self.nBytesNodeAddress
+                iAddr = iEndArcAddr + 1
             return l
         return []
 
     def _lookupArcNode1 (self, nVal, iAddr):
         "looks if <nVal> is an arc at the node at <iAddr>, if yes, returns address of next node else None"
         while True:
-            iEndArcAddr = iAddr+self.nBytesArc
-            nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
+            iEndArcAddr = iAddr + 1
+            nRawArc = self.byDic[iAddr]
             if nVal == (nRawArc & self._arcMask):
                 # the value we are looking for
                 # we return the address of the next node
-                return int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
+                return self.byDic[iEndArcAddr]
             # value not found
             if nRawArc & self._lastArcMask:
                 return None
-            iAddr = iEndArcAddr+self.nBytesNodeAddress
+            iAddr = iEndArcAddr + 1
 
     def _getArcs1 (self, iAddr):
         "generator: return all arcs at <iAddr> as tuples of (nVal, iAddr)"
         while True:
-            iEndArcAddr = iAddr+self.nBytesArc
-            nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
-            yield nRawArc & self._arcMask, int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], byteorder='big')
+            iEndArcAddr = iAddr + 1
+            nRawArc = self.byDic[iAddr]
+            yield nRawArc & self._arcMask, self.byDic[iEndArcAddr]
             if nRawArc & self._lastArcMask:
                 break
-            iAddr = iEndArcAddr+self.nBytesNodeAddress
+            iAddr = iEndArcAddr + 1
 
     def _writeNodes1 (self, spfDest):
         "for debugging only"
         print(" > Write binary nodes")
         with open(spfDest, 'w', 'utf-8', newline="\n") as hDst:
             iAddr = 0
             hDst.write("i{:_>10} -- #{:_>10}\n".format("0", iAddr))
             while iAddr < len(self.byDic):
-                iEndArcAddr = iAddr+self.nBytesArc
-                nRawArc = int.from_bytes(self.byDic[iAddr:iEndArcAddr], byteorder='big')
+                iEndArcAddr = iAddr + 1
+                nRawArc = self.byDic[iAddr]
                 nArc = nRawArc & self._arcMask
-                hDst.write("  {:<20}  {:0>16}  i{:>10}   #{:_>10}\n".format(self.lArcVal[nArc], bin(nRawArc)[2:], "?", \
-                                                                            int.from_bytes(self.byDic[iEndArcAddr:iEndArcAddr+self.nBytesNodeAddress], \
-                                                                                           byteorder='big')))
-                iAddr = iEndArcAddr+self.nBytesNodeAddress
+                hDst.write("  {:<20}  {:0>16}  i{:>10}   #{:_>10}\n".format(self.lArcVal[nArc], bin(nRawArc)[2:], "?", self.byDic[iEndArcAddr]))
+                iAddr = iEndArcAddr + 1
                 if (nRawArc & self._lastArcMask) and iAddr < len(self.byDic):
                     hDst.write("\ni{:_>10} -- #{:_>10}\n".format("?", iAddr))
             hDst.close()
 
     # VERSION 2