{"id":30313,"date":"2006-07-28T10:00:00","date_gmt":"2006-07-28T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/07\/28\/the-efficiency-of-ordinal-based-imports-while-still-being-name-based\/"},"modified":"2006-07-28T10:00:00","modified_gmt":"2006-07-28T10:00:00","slug":"the-efficiency-of-ordinal-based-imports-while-still-being-name-based","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060728-00\/?p=30313","title":{"rendered":"The efficiency of ordinal-based imports while still being name-based"},"content":{"rendered":"<p><a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/07\/18\/669668.aspx#669832\"> Reader Tom brought up the interesting point that ordinal-based imports are slightly faster than name-based<\/a>, though not by much. But if even that tiny fraction of a percentage bothers you, you can still get the benefits of ordinal-based imports while still being name-based.\n People are more familiar with the first half of the &#8220;rebase and bind&#8221; duo than the second. But it&#8217;s binding that speeds up import table resolution. When a DLL is &#8220;bound&#8221; to another DLL, information about the target DLL is cached in the original DLL. Specifically, the timestamp of the target (so that the loader can detect whether the cache is valid), the ordinal corresponding to the name (the &#8220;hint&#8221;), and the address of the ultimate function. For example, if I had a DLL that linked to <code>kernel32!LocalAlloc<\/code> the entry in the DLL would go something like this:\n &#8220;Hello. I would like to link to these functions in <code>kernel32<\/code>. Oh, and by the way, all the hints I&#8217;m about to give you are based on the Aug 04 00:56:36 2004 version of <code>KERNEL32.DLL<\/code>. As for the function <code>LocalAlloc<\/code>, I believe that the function resides at address 0x7C8099BD, and that you&#8217;ll find it in <code>kernel32<\/code>&#8216;s named export table in position 247.&#8221;<\/p>\n<p> When the loader goes to resolve the import, it checks the timestamp of the target file on the computer with the one cached in the DLL. If they match, then it doesn&#8217;t need to do any look-ups at all; it justs uses the cached value (0x7C8099BD). If they don&#8217;t match (for example, maybe there was a <code>kernel32<\/code> hot-fix), it can still use the look-up hint: Before doing the binary search for <code>LocalAlloc<\/code>, it looks directly at slot 247 to see if <code>LocalAlloc<\/code> is there. If so, then the cost of the binary search has been avoided, and the overhead of the look-up over a pure ordinal import is just one string comparison. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Reader Tom brought up the interesting point that ordinal-based imports are slightly faster than name-based, though not by much. But if even that tiny fraction of a percentage bothers you, you can still get the benefits of ordinal-based imports while still being name-based. People are more familiar with the first half of the &#8220;rebase and [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-30313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Reader Tom brought up the interesting point that ordinal-based imports are slightly faster than name-based, though not by much. But if even that tiny fraction of a percentage bothers you, you can still get the benefits of ordinal-based imports while still being name-based. People are more familiar with the first half of the &#8220;rebase and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=30313"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30313\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=30313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=30313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=30313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}