[latex3-commits] [git/LaTeX3-latex3-luaotfload] bidi-dev: Other table structure. Might be faster (49f9d8a)

Marcel Fabian Krüger tex at 2krueger.de
Tue Aug 13 02:42:26 CEST 2019


Repository : https://github.com/latex3/luaotfload
On branch  : bidi-dev
Link       : https://github.com/latex3/luaotfload/commit/49f9d8ae3656fad75eb816aa1dde124b73deb15a

>---------------------------------------------------------------

commit 49f9d8ae3656fad75eb816aa1dde124b73deb15a
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Sat Aug 10 15:35:51 2019 +0200

    Other table structure. Might be faster


>---------------------------------------------------------------

49f9d8ae3656fad75eb816aa1dde124b73deb15a
 src/luaotfload-bidi.lua | 107 ++++++++++++++++++++++++++----------------------
 1 file changed, 57 insertions(+), 50 deletions(-)

diff --git a/src/luaotfload-bidi.lua b/src/luaotfload-bidi.lua
index 387accb..f67d01b 100644
--- a/src/luaotfload-bidi.lua
+++ b/src/luaotfload-bidi.lua
@@ -143,18 +143,21 @@ local NI = {
   PDI = true,
 }
 
-local function adjust_nsm(pre, dir, node_type)
+local function adjust_nsm(pre, dir, node_origclass)
   local follow = getnext(pre)
-  local follow_type = node_type[follow]
-  while follow ~= stop and (not follow_type[2] or follow_type[3] == "NSM") do
-    if follow_type[2] then
-      follow_type[2] = dir
+  local follow_origclass = node_origclass[follow]
+  while follow ~= stop and (not follow_origclass or follow_origclass == "NSM") do
+    if follow_origclass then
+      follow_class = dir
     end
     follow = getnext(follow)
-    follow_type = node_type[follow]
+    follow_origclass = node_origclass[follow]
   end
 end
-function do_wni(head, level, stop, sos, eos, node_type)
+local gettime = socket.gettime
+local fulltime1, fulltime2, fulltime3 = 0, 0, 0
+function do_wni(head, level, stop, sos, eos, node_class, node_level, node_origclass)
+  local starttime = gettime()
   local opposite, direction
   if level % 2 == 0 then
     direction, opposite = 'L', 'R'
@@ -167,17 +170,16 @@ function do_wni(head, level, stop, sos, eos, node_type)
   -- faster.
   local cur = head
   while cur ~= stop do
-    local curtype = node_type[cur]
-    local curclass = curtype[1]
+    local curclass = node_class[cur]
     if curclass == "NSM" then
       curclass = prevclass == "PDI" and "ON" or prevclass
-      curtype[1] = curclass
+      node_class[cur] = curclass
     elseif curclass == "EN" then
       if prevstrong == "AL" then
         curclass = "AN"
-        curtype[1] = curclass
+        node_class[cur] = curclass
       elseif prevstrong == "L" then
-        curtype[1] = "L"
+        node_class[cur] = curclass
         -- HACK: No curclass change. Therefore prevclass is still EN,
         -- such that this W7 change does not affect the ES/ET changes
         -- in W4-W5
@@ -185,17 +187,17 @@ function do_wni(head, level, stop, sos, eos, node_type)
     elseif curclass == "ES" then
       if prevclass == "EN" then
         local follow = getnext(cur)
-        local followclass = node_type[follow][1]
+        local followclass = node_class[cur]
         while follow ~= stop and not followclass do
           follow = getnext(follow)
-          followclass = follow and node_type[follow][1]
+          followclass = node_class[follow]
         end
         if follow ~= stop and followclass == "EN" then
           if prevstrong == "AL" then
             curclass = "AN"
-            curtype[1] = curclass
+            node_class[cur] = curclass
           elseif prevstrong == "L" then
-            curtype[1] = "L"
+            node_class[cur] = "L"
             curclass = "EN" -- (sic), see above
           end
         end
@@ -203,48 +205,48 @@ function do_wni(head, level, stop, sos, eos, node_type)
     elseif curclass == "CS" then
       if prevclass == "EN" or prevclass == "AN" then
         local follow = getnext(cur)
-        local followclass = node_type[follow][1]
+        local followclass = node_class[follow]
         while follow ~= stop and not followclass do
           follow = getnext(follow)
-          followclass = follow and node_type[follow][1]
+          followclass = node_class[follow]
         end
         if follow ~= stop and followclass == prevclass then
           if followclass == "EN" then
             if prevstrong == "AL" then
               curclass = "AN"
-              curtype[1] = curclass
+              node_class[cur] = curclass
             elseif prevstrong == "L" then
-              curtype[1] = "L"
+              node_class[cur] = "L"
               curclass = "EN" -- (sic), see above
             end
           else
             curclass = prevclass
-            curtype[1] = curclass
+            node_class[cur] = curclass
           end
         else
           curclass = "ON"
-          curtype[1] = curclass
+          node_class[cur] = curclass
         end
       else
         curclass = "ON"
-        curtype[1] = curclass
+        node_class[cur] = curclass
       end
     elseif curclass == "ET" then
       local follow = getnext(cur)
-      local followclass = node_type[follow][1]
+      local followclass = node_class[follow]
       while follow ~= stop and (followclass == "ET" or not followclass) do
         follow = getnext(follow)
-        followclass = follow and node_type[follow][1]
+        followclass = node_class[follow]
       end
       if followclass == "EN" then
         follow = cur
         followclass = curclass
         while follow ~= stop and (followclass == "ET" or not followclass) do
           if followclass then
-            node_type[follow][1] = "EN"
+            node_class[follow] = "EN"
           end
           follow = getnext(follow)
-          followclass = follow and node_type[follow][1]
+          followclass = node_class[follow]
         end
       else
         curclass = "ON"
@@ -282,16 +284,17 @@ function do_wni(head, level, stop, sos, eos, node_type)
                 stack[j] = nil
               end
               if last_e >= i then
-                local btype, etype = node_type[entry[1]], node_type[cur]
-                btype[1], etype[1] = direction, direction
-                adjust_nsm(entry[1], direction, node_type)
-                adjust_nsm(cur, direction, node_type)
+                local beg = entry[1]
+                node_class[beg], node_class[cur] = direction, direction
+                adjust_nsm(beg, direction, node_origclass)
+                adjust_nsm(cur, direction, node_origclass)
                 last_s, last_e = i-1, i-1
               elseif last_s >= i then
                 if entry[3] then
-                  local btype, etype = node_type[entry[1]], node_type[cur]
-                  adjust_nsm(entry[1], opposite, node_type)
-                  adjust_nsm(cur, opposite, node_type)
+                  local beg = entry[1]
+                  node_class[beg], node_class[cur] = opposite, opposite
+                  adjust_nsm(beg, opposite, node_origclass)
+                  adjust_nsm(cur, opposite, node_origclass)
                   btype[1], etype[1] = opposite, opposite
                 end
                 last_s = i-1
@@ -301,7 +304,7 @@ function do_wni(head, level, stop, sos, eos, node_type)
           end
         end
       else
-        local curclass = node_type[cur][1]
+        local curclass = node_class[cur]
         if Strong[curclass] == direction then
           last_e, last_s, prevstrong = #stack, #stack, direction
         elseif Strong[curclass] == opposite then
@@ -325,19 +328,18 @@ function do_wni(head, level, stop, sos, eos, node_type)
     EN = level+1,
   }
   while cur ~= stop do
-    local curtype = node_type[cur]
-    local curclass = curtype[1]
+    local curclass = node_class[cur]
     local strong = Strong[curclass]
     if strong then
       prevstrong = strong
-      curtype[2] = newlevels[curclass]
+      node_level[cur] = newlevels[curclass]
       cur = getnext(cur)
     else
       local follow = getnext(cur)
-      local followclass = follow and node_type[follow][1]
+      local followclass = node_class[follow]
       while follow ~= stop and not Strong[followclass] do
         follow = getnext(follow)
-        followclass = follow and Strong[node_type[follow][1]]
+        followclass = Strong[node_class[follow]]
       end
       if follow == stop then
         followclass = eos
@@ -346,21 +348,22 @@ function do_wni(head, level, stop, sos, eos, node_type)
       follow = cur
       followclass = curclass
       while follow ~= stop and not Strong[followclass] do
-        follow_type = node_type[follow]
-        follow_type[1], follow_type[2] = followclass and outerdir, followclass and newlevels[outerdir]
+        node_class[follow], node_level[follow] = followclass and outerdir, followclass and newlevels[outerdir]
         follow = getnext(follow)
-        followclass = follow and node_type[follow][1]
+        followclass = node_class[follow]
       end
       cur = follow
     end
   end
+  fulltime1 = fulltime1 + gettime() - starttime
 end
 function dobidi(head, a, b, c, par_direction)
+  local starttime = gettime()
   head = node.direct.todirect(head)
   -- for cur in traverse(head) do
   --   print(node.direct.tonode(cur))
   -- end
-  local node_type = {} -- We do not need to preserve the direction types, so this is faster than using properties
+  local node_class, node_origclass, node_level = {}, {}, {} -- We do not need to preserve the direction types, so this is faster than using properties
   local dir_matches = {}
   par_direction = par_direction == "TRT" and "R" or "L" -- We hope to only encounter TRT/TLT
   local level, overwrite, isolate = par_direction == "R" and 1 or 0
@@ -439,7 +442,7 @@ function dobidi(head, a, b, c, par_direction)
     else
       class = "ON"
     end
-    node_type[cur] = {class, curlevel or level, class}
+    node_class[cur], node_origclass[cur], node_level[cur] = class, class, curlevel or level
   end
   for i = 1,#stack do pop() end
   local parlevel = level
@@ -453,8 +456,7 @@ function dobidi(head, a, b, c, par_direction)
         setchar(cur, char)
       end
     end
-    local curtype = node_type[cur]
-    local curclass, curlevel = curtype[1], curtype[2]
+    local curclass, curlevel = node_class[cur], node_level[cur]
     if curlevel ~= level and curclass then
       local os = (level > curlevel and level or curlevel) % 2 == 1 and 'R' or 'L'
       level = curlevel
@@ -493,10 +495,12 @@ function dobidi(head, a, b, c, par_direction)
     -- Should always be level IINM, but let's us the offical check
     current_run = nil
   end
+  fulltime2 = fulltime2 + gettime() - starttime
   for i = 1, #isolating_level_runs do
     local run = isolating_level_runs[i]
-    do_wni(run[1], run[2], run[3], run[4], run[5], node_type)
+    do_wni(run[1], run[2], run[3], run[4], run[5], node_class, node_level, node_origclass)
   end
+  starttime = gettime()
   -- for cur in traverse(head) do
   --   local curtype = node_type[cur]
   --   local curclass, curlevel, origtype = curtype[1], curtype[2], curtype[3]
@@ -537,8 +541,7 @@ function dobidi(head, a, b, c, par_direction)
     return insert_before(head, n, dirnode), entry[2]
   end
   for cur, tcur, scur in traverse(head) do
-    local curtype = node_type[cur]
-    local curlevel = curtype[2]
+    local curlevel = node_level[cur]
     if tcur == dir_id and scur == 1 then
       local newlevel = curlevel + (curlevel + getdirection(cur) + 1)%2 + 1
       while level > newlevel do
@@ -568,9 +571,13 @@ function dobidi(head, a, b, c, par_direction)
   --   local dir = not curtype and getdirection(cur)
   --   print('_', node.direct.tonode(cur), curlevel, curtype and curtype[1], dir)
   -- end
+  fulltime3 = fulltime3 + gettime() - starttime
   return node.direct.tonode(head)
 end
 
+luatexbase.add_to_callback("stop_run", function()
+  print('fulltime', fulltime1, fulltime2, fulltime3)
+end, "mytimer")
 otffeatures.register {
   name        = "bidi",
   description = "Apply Unicode bidi algorithm",





More information about the latex3-commits mailing list