{"id":327,"date":"2008-03-30T16:32:31","date_gmt":"2008-03-30T20:32:31","guid":{"rendered":"http:\/\/www.rakkar.org\/blog\/?p=327"},"modified":"2008-03-30T16:32:31","modified_gmt":"2008-03-30T20:32:31","slug":"additional-rakstring-optimizations","status":"publish","type":"post","link":"https:\/\/rakkar.org\/blog\/index.php\/2008\/03\/30\/additional-rakstring-optimizations\/","title":{"rendered":"Additional RakString optimizations"},"content":{"rendered":"<p>\t\t\t\tI removed a couple of conditions, inlined and unrolled a function, and replaced the generic memory pool with a stack of pointers.<\/p>\n<p><b>RakString vs. std::string<\/b><br \/>\nCreation: RakString roughly fixed cost. std::string improves over time. Depending on when the test occurs, RakString ranges from 3X faster to roughly equal.<br \/>\nRemove at head (shifting a large list): RakString is consistently 4.25X faster<br \/>\nDeletion: Both are fast enough to not register one millisecond.<\/p>\n<p><b>5000 iterations<\/b><br \/>\nReference is new \/ delete and strcpy with a straight char*<\/p>\n<p>Insertion 1 Ref=5 Rak=13, Std=48<br \/>\nRemoveHead Ref=18 Rak=150, Std=674<br \/>\nInsertion 2 Ref=5 Rak=6, Std=13<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<br \/>\nInsertion 1 Ref=6 Rak=7, Std=5<br \/>\nRemoveHead Ref=30 Rak=153, Std=673<br \/>\nInsertion 2 Ref=8 Rak=6, Std=5<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<br \/>\nInsertion 1 Ref=6 Rak=7, Std=8<br \/>\nRemoveHead Ref=62 Rak=151, Std=666<br \/>\nInsertion 2 Ref=7 Rak=7, Std=8<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<br \/>\nInsertion 1 Ref=6 Rak=7, Std=13<br \/>\nRemoveHead Ref=61 Rak=156, Std=669<br \/>\nInsertion 2 Ref=11 Rak=7, Std=12<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<\/p>\n<p><b>10000 iterations<\/b><\/p>\n<p>Insertion 1 Ref=13 Rak=26, Std=141<br \/>\nRemoveHead Ref=58 Rak=1167, Std=3425<br \/>\nInsertion 2 Ref=12 Rak=13, Std=7<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<br \/>\nInsertion 1 Ref=13 Rak=13, Std=30<br \/>\nRemoveHead Ref=108 Rak=1122, Std=3334<br \/>\nInsertion 2 Ref=12 Rak=14, Std=29<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<br \/>\nInsertion 1 Ref=10 Rak=14, Std=22<br \/>\nRemoveHead Ref=878 Rak=1116, Std=3363<br \/>\nInsertion 2 Ref=12 Rak=13, Std=23<br \/>\nRemoveTail Ref=1 Rak=0, Std=0<br \/>\nInsertion 1 Ref=13 Rak=13, Std=14<br \/>\nRemoveHead Ref=886 Rak=1128, Std=3349<br \/>\nInsertion 2 Ref=14 Rak=14, Std=14<br \/>\nRemoveTail Ref=0 Rak=0, Std=0<\/p>\n<p><b>Summary<\/b><\/p>\n<p>Reference is  much faster in shifting large lists because it is just copying a single variable internally. Neither std::string nor RakString know that contextually they don&#8217;t need to do intermediate copies, so there is more overhead and thus they are slower. However, RakString uses a reference counted pointer, so the shifting is limited to a few variables vs. std::string which actually does a full copy. RakString is about 20% slower than reference, but std::string is over 350% slower.<\/p>\n<p>Reference is much faster the first iteration, because RakString has to create the memory pools. Presumably std::string does this as well. After the first iteration, RakString varies from equally fast to 50% slower. std::string varies from equally fast to 250% slower. However, oddly enough in one test std::string was faster than both &#8211; this was probably a fluke due to thread context switching.<\/p>\n<p>While it doesn&#8217;t show in these numbers, in some later tests reference got slower the more tests I ran, until it was actually far slower than both RakString and std::string. This was probably due to memory fragmentation.<\/p>\n<p>If you are going to do a lot of shifting around in lists, just use char* that you allocated yourself. Otherwise, use RakString. RakString is faster than std::string, and doesn&#8217;t cause linker errors and export warnings when linking as a DLL, a big plus. The constructor and Set function is varidic. It complies with camelCase conventions. And as I use it more I can add inherent functionality that std::string is missing, such as splitpath.<\/p>\n<p>Here&#8217;s the code. It&#8217;s stand-alone except for DS_List, and SimpleMutex. For the export and assertions you can just replace those with your own versions. SimpleMutex could be removed if this was only used in a single thread at a single time.<\/p>\n<p><a HREF=\"http:\/\/raknetjenkinsso.svn.sourceforge.net\/viewvc\/*checkout*\/raknetjenkinsso\/trunk\/Source\/RakString.h\">Header<\/a><br \/>\n<a HREF=\"http:\/\/raknetjenkinsso.svn.sourceforge.net\/viewvc\/*checkout*\/raknetjenkinsso\/trunk\/Source\/RakString.cpp\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I removed a couple of conditions, inlined and unrolled a function, and replaced the generic memory pool with a stack of pointers. RakString vs. std::string Creation: RakString roughly fixed cost. std::string improves over time. Depending on when the test occurs, RakString ranges from 3X faster to roughly equal. Remove at head (shifting a large list): [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/327"}],"collection":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=327"}],"version-history":[{"count":0,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/327\/revisions"}],"wp:attachment":[{"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rakkar.org\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}