Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addAndGetMenuItem is suprisingly slow #166

Open
ericu opened this issue Jul 24, 2020 · 8 comments
Open

addAndGetMenuItem is suprisingly slow #166

ericu opened this issue Jul 24, 2020 · 8 comments

Comments

@ericu
Copy link
Contributor

ericu commented Jul 24, 2020

I was profiling to figure out why an operation in my code was slow, and it turned out that it wasn't at all--it was that I was updating a few menus with the result of the operation. Apparently down inside addAndGetMenuItem in my app there are 32454 calls to getMenuItemByIndex'. I do have a lot of stuff in my menus [I generate them based on what's in my database, so that you can select from any defined item]; it looks like I have somewhere north of 8000 of them, though far less than 32K. Here I'm updating a submenu with about a dozen entries by clearing it, putting back the standard items, and adding a new one to represent a newly-created object. What's the fast way to do this, or can addAndGetMenuItem be sped up?

The reason I'm using addAndGetMenuItem is to have a handle to the menu item [a toggle button] so that I can call "set" on it if it's the active item. If I could just add it with some flag that makes it set, I'd do that instead, but I don't see a flag for that. Perhaps I'm missing something?

@ericu
Copy link
Contributor Author

ericu commented Jul 24, 2020

         addAndGetMenuItem                                                       Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:2700:164-293             65390          3    0.0    0.0    66.2   88.5
          dispatch                                                               Graphics.UI.FLTK.LowLevel.Dispatch                  src/Graphics/UI/FLTK/LowLevel/Dispatch.hs:151:1-83                  65396         12    0.0    0.0    66.2   88.5
           castTo                                                                Graphics.UI.FLTK.LowLevel.Dispatch                  src/Graphics/UI/FLTK/LowLevel/Dispatch.hs:134:1-24                  65398         12    0.0    0.0     0.0    0.0
           runOp                                                                 Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:243:3-63            65460          3    0.0    0.0     0.0    0.0
            withRef                                                              Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65461          3    0.0    0.0     0.0    0.0
             throwStackOnError                                                   Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65462          3    0.0    0.0     0.0    0.0
           runOp                                                                 Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(144,3)-(156,29)    65449          3    0.0    0.0     0.0    0.0
            withRef                                                              Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65450          3    0.0    0.0     0.0    0.0
             throwStackOnError                                                   Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65451          3    0.0    0.0     0.0    0.0
           runOp                                                                 Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(229,3)-(230,91)    65405          3    0.0    0.0     0.0    0.0
            addMenuItem                                                          Graphics.UI.FLTK.LowLevel.Base.MenuItem             src/Graphics/UI/FLTK/LowLevel/Base/MenuItem.chs:(287,1)-(328,29)    65406          3    0.0    0.0     0.0    0.0
             addMenuItem.\                                                       Graphics.UI.FLTK.LowLevel.Base.MenuItem             src/Graphics/UI/FLTK/LowLevel/Base/MenuItem.chs:(289,18)-(290,73)   65407          3    0.0    0.0     0.0    0.0
              withRef                                                            Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65408          3    0.0    0.0     0.0    0.0
               throwStackOnError                                                 Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65409          3    0.0    0.0     0.0    0.0
             addMenuItem.go                                                      Graphics.UI.FLTK.LowLevel.Base.MenuItem             src/Graphics/UI/FLTK/LowLevel/Base/MenuItem.chs:(296,7)-(328,29)    65424          0    0.0    0.0     0.0    0.0
              addMenuItem.go.combinedFlags                                       Graphics.UI.FLTK.LowLevel.Base.MenuItem             src/Graphics/UI/FLTK/LowLevel/Base/MenuItem.chs:297:13-52           65438          0    0.0    0.0     0.0    0.0
               menuItemFlagsToInt                                                Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:387:1-74                     65439          0    0.0    0.0     0.0    0.0
                combine                                                          Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:159:1-52                     65440          0    0.0    0.0     0.0    0.0
                 fromEnum                                                        Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(263,3)-(272,35)         65441          3    0.0    0.0     0.0    0.0
              copyTextToCString                                                  Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:(441,1)-(444,30)             65425          0    0.0    0.0     0.0    0.0
               copyTextToCString.bs                                              Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:442:7-25                     65426          0    0.0    0.0     0.0    0.0
           runOp                                                                 Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(233,3)-(239,195)   65397          3    0.0    0.0    66.2   88.5
            add                                                                  Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:1978:106-207             65399          3    0.0    0.0     0.0    0.0
             withRef                                                             Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65400          3    0.0    0.0     0.0    0.0
              throwStackOnError                                                  Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65401          3    0.0    0.0     0.0    0.0
               withRef.\                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(470,25)-(472,29)        65402          3    0.0    0.0     0.0    0.0
                add.\                                                            Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:1978:156-164             65404          3    0.0    0.0     0.0    0.0
                toRefPtr                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(460,1)-(464,21)         65403          3    0.0    0.0     0.0    0.0
            getMenu                                                              Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:2680:122-231             65443          3    0.0    0.0     0.0    0.0
             withRef                                                             Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65444          3    0.0    0.0     0.0    0.0
              throwStackOnError                                                  Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65445          3    0.0    0.0     0.0    0.0
               withRef.\                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(470,25)-(472,29)        65446          3    0.0    0.0     0.0    0.0
                getMenu.\                                                        Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:2680:176-184             65448          3    0.0    0.0     0.0    0.0
                toRefPtr                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(460,1)-(464,21)         65447          3    0.0    0.0     0.0    0.0
            runOp.mi                                                             Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:236:9-23            65478          3    0.0    0.0     0.0    0.0
            runOp                                                                Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(144,3)-(156,29)    65452          0    0.0    0.0    66.2   88.5
             withRef                                                             Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(467,1)-(473,8)          65453          3    0.0    0.0    66.2   88.5
              throwStackOnError                                                  Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(446,1)-(450,47)         65454      32454    0.0    0.0    66.2   88.5
               withRef.\                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(470,25)-(472,29)        65455          9    0.0    0.0    66.2   88.5
                toRefPtr                                                         Graphics.UI.FLTK.LowLevel.Fl_Types                  src/Graphics/UI/FLTK/LowLevel/Fl_Types.chs:(460,1)-(464,21)         65456          9    0.0    0.0     0.0    0.0
                getSize.\                                                        Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:2612:176-184             65459          3    0.0    0.0     0.0    0.0
                runOp.\                                                          Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:243:50-63           65464          3    0.0    0.0     0.0    0.0
                 size'                                                           Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(242,1)-(246,15)    65465          3    0.0    0.0     0.0    0.0
                  size'.\                                                        Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(245,3)-(246,15)    65467          3    0.0    0.0     0.0    0.0
                   size'.\.res'                                                  Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:245:8-30            65468          3    0.0    0.0     0.0    0.0
                  size'.a1'                                                      Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:243:8-18            65466          3    0.0    0.0     0.0    0.0
                runOp.\                                                          Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(144,50)-(148,32)   65457          3    0.0    0.0    66.2   88.5
                 runOp.go                                                        Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(150,9)-(156,29)    65469      32454   66.1   88.3    66.2   88.5
                  getMenuItemByIndex'                                            Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(143,1)-(148,15)    65470      32451    0.0    0.0     0.0    0.0
                   getMenuItemByIndex'.\                                         Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:(147,3)-(148,15)    65473      32451    0.0    0.0     0.0    0.0
                    getMenuItemByIndex'.\.res'                                   Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:147:8-20            65475      32451    0.0    0.0     0.0    0.0
                   getMenuItemByIndex'.a1'                                       Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:144:8-18            65471      32451    0.0    0.0     0.0    0.0
                   getMenuItemByIndex'.a2'                                       Graphics.UI.FLTK.LowLevel.Base.MenuPrim             src/Graphics/UI/FLTK/LowLevel/Base/MenuPrim.chs:145:8-18            65472      32451    0.0    0.0     0.0    0.0
                  toMaybeRef                                                     Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:357:1-90                     65474      32451    0.0    0.0     0.1    0.1
                   toRef                                                         Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:(326,1)-(330,35)             65476      32451    0.0    0.0     0.1    0.1
                    wrapNonNull                                                  Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:(190,1)-(195,57)             65477      32451    0.1    0.1     0.1    0.1
                    toRef.result                                                 Graphics.UI.FLTK.LowLevel.Utils                     src/Graphics/UI/FLTK/LowLevel/Utils.hs:329:25-45                    65483          3    0.0    0.0     0.0    0.0
                 getSize                                                         Graphics.UI.FLTK.LowLevel.Hierarchy                 src/Graphics/UI/FLTK/LowLevel/Hierarchy.hs:2612:122-231             65458          3    0.0    0.0     0.0    0.0
                 runOp

@ericu
Copy link
Contributor Author

ericu commented Jul 25, 2020

It occurs to me that in the C FLTK the AtIndex is much more useful. You can call menu() to get the underlying array of menus, and then menu()[atIndex] should be the menu item you want to modify. In your wrapper, there's no way I see to do that, so I had to use this function that does a linear search.

Huh. Looking at the source of AddAndGetMenuItem really looks like it's doing what I'd want to do. I think it must be doing something per-menu-item that's not obvious from the code, which looks no more expensive than a list traversal:

instance (Parent a MenuItemBase, impl ~ ( T.Text -> Maybe Shortcut -> Maybe (Ref a-> IO ()) -> MenuItemFlags -> IO (Ref MenuItemBase))) => Op (AddAndGetMenuItem ()) MenuPrimBase orig (impl) where
runOp _ _ menu_ name shortcut cb flags = do
(AtIndex i) <- add menu_ name shortcut cb flags
items <- getMenu menu_
let mi = items !! i
case mi of
Just mi' -> return mi'
Nothing -> throwIO (userError ("FLTK claims the menu item " ++ (T.unpack name) ++ " was added successfully at index " ++ (show i) ++ " , but no MenuItem at that index could be retrieved."))

Perhaps it's forcing some conversion on each list item by iterating past them? Could it be lazier?

@deech
Copy link
Owner

deech commented Jul 25, 2020

Off the bat I see that getMenu is retrieving all the items in the menu and iterating through them to find the one you just added, so essentially it's the painter's algorithm.

Honestly I didn't see the menus being used this way so I went with a very naive approach. An incremental improvement might be to have getMenu return a Vector instead of a List.

@ericu
Copy link
Contributor Author

ericu commented Jul 25, 2020

Could AddAndGetMenuItem just call into getMenuItemByIndex' more directly, as getMenu is?

@deech
Copy link
Owner

deech commented Jul 25, 2020

Yes that might work well. I'll try to get to it as soon as I can but you are able to I'm happy to merge a PR.

@ericu
Copy link
Contributor Author

ericu commented Jul 25, 2020

Thanks! Exposing getMenuItemByIndex would also be great.

@ericu
Copy link
Contributor Author

ericu commented Jul 25, 2020

Heh; and in this case, the flag I was looking for was MenuItemValue, so I'm just going to call add instead of addAndGetMenuItem 😁. So no rush on my account, but it does look likely to be a quick fix when you get around to it.

@ericu
Copy link
Contributor Author

ericu commented Jul 25, 2020

I'm also going to see about reducing my menu count by a factor of 80-100; there's a small change that would do it, and now that I know how many there are, it seems kind of ridiculous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants