{"id":2258,"date":"2016-09-07T09:33:26","date_gmt":"2016-09-07T07:33:26","guid":{"rendered":"http:\/\/mariusbancila.ro\/blog\/?p=2258"},"modified":"2016-09-12T13:28:17","modified_gmt":"2016-09-12T11:28:17","slug":"a-comparison-of-two-stdtransform-alternatives","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/","title":{"rendered":"A comparison of two std::transform alternatives"},"content":{"rendered":"<p><strong>UPDATE<\/strong>: For an update on the implementation and the conclusions see <a href=\"http:\/\/mariusbancila.ro\/blog\/2016\/09\/12\/a-comparison-of-two-stdtransform-alternatives-revisited\/\">A comparison of two std::transform alternatives revisited<\/a>.<\/p>\n<p>I was writing a small utility function to transform a string to uppercase. The obvious solution for that is <tt>std::transform<\/tt>, but as I was writing it I realized there are several alternatives:<\/p>\n<ul>\n<li>transform an existing string, by setting its elements to uppercase one by one<\/li>\n<li>iterate over an existing string, and insert a copy of its uppercased elements into another string, initially empty, using <tt>std::back_inserter<\/tt><\/li>\n<\/ul>\n<p>Obviously, the second approach should be slower since it has to deal with buffer reallocations. However, I was curious how slower comparing to the first approach that would be. So I decided to test it.<\/p>\n<p><strong>UPDATE<\/strong>: It has been suggested that in the second version I should make a reserve of the string before using <tt>std::back_inserter<\/tt> to add characters to the string. Therefore I added a 3rd version that does that. <\/p>\n<p>This is how I implemented the <del datetime=\"2016-09-08T07:08:13+00:00\">two version<\/del> different versions of the helper function:<\/p>\n<pre class=\"lang:default decode:true \" >inline std::string to_upper_v1(std::string const &amp; text)\r\n{\r\n  auto uppertext { text };\r\n  std::transform(std::begin(uppertext), std::end(uppertext), std::begin(uppertext), toupper);\r\n  return uppertext;\r\n}\r\n\r\ninline std::string to_upper_v2(std::string const &amp; text)\r\n{\r\n  auto uppertext = std::string{};\r\n  std::transform(std::begin(text), std::end(text), std::back_inserter(uppertext), toupper);\r\n  return uppertext;\r\n}\r\n\r\ninline std::string to_upper_v3(std::string const &amp; text)\r\n{\r\n   auto uppertext = std::string{};\r\n   uppertext.reserve(text.size());\r\n   std::transform(std::begin(text), std::end(text), std::back_inserter(uppertext), toupper);\r\n   return uppertext;\r\n}\r\n<\/pre>\n<p>To test it, I decided to randomly generate strings. The length of the strings and their content is randomly generated. Both functions are tested with the same strings after a copy is initially done.<\/p>\n<pre class=\"lang:default decode:true \" >void test_v1(std::vector&lt;std::string&gt;&amp; strings)\r\n{\r\n   auto start{ std::chrono::high_resolution_clock::now() };\r\n   for (auto&amp; s : strings)\r\n   {\r\n      to_upper_v1(s);\r\n   }\r\n\r\n   auto end{ std::chrono::high_resolution_clock::now() };\r\n   auto duration{ std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - start).count() };\r\n   std::cout &lt;&lt; \"duration v1 (\" &lt;&lt; strings.size() &lt;&lt; \") = \" &lt;&lt; duration &lt;&lt; std::endl;\r\n}\r\n\r\nvoid test_v2(std::vector&lt;std::string&gt;&amp; strings)\r\n{\r\n   auto start{ std::chrono::high_resolution_clock::now() };\r\n   for (auto&amp; s : strings)\r\n   {\r\n      to_upper_v2(s);\r\n   }\r\n\r\n   auto end{ std::chrono::high_resolution_clock::now() };\r\n   auto duration{ std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - start).count() };\r\n   std::cout &lt;&lt; \"duration v2 (\" &lt;&lt; strings.size() &lt;&lt; \") = \" &lt;&lt; duration &lt;&lt; std::endl;\r\n}\r\n\r\nvoid test_v3(std::vector&lt;std::string&gt;&amp; strings)\r\n{\r\n   auto start{ std::chrono::high_resolution_clock::now() };\r\n   for (auto&amp; s : strings)\r\n   {\r\n      to_upper_v3(s);\r\n   }\r\n\r\n   auto end{ std::chrono::high_resolution_clock::now() };\r\n   auto duration{ std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - start).count() };\r\n   std::cout &lt;&lt; \"duration v3 (\" &lt;&lt; strings.size() &lt;&lt; \") = \" &lt;&lt; duration &lt;&lt; std::endl;\r\n}\r\n\r\nint main()\r\n{ \r\n   auto seed_data = std::array&lt;int, std::mt19937::state_size&gt; {};\r\n   std::random_device rd;\r\n\r\n   std::generate(std::begin(seed_data), std::begin(seed_data), std::ref(rd));\r\n   std::seed_seq seq(std::begin(seed_data), std::end(seed_data));\r\n   auto eng = std::mt19937{ seq };\r\n   auto dist_len = std::uniform_int_distribution&lt;&gt;{ 3, 12 };\r\n   auto dist_char = std::uniform_int_distribution&lt;&gt;{ 0, 25 };\r\n\r\n   auto strings = std::vector&lt;std::string&gt;{};\r\n   strings.reserve(100000000);\r\n   for (auto i = 0; i &lt; 100000000; ++i)\r\n   {\r\n      auto length = dist_len(eng);\r\n      auto text = std::string(length, '\\0');\r\n      std::generate(std::begin(text), std::end(text), [&amp;dist_char, &amp;eng]() {return 'a' + dist_char(eng); });\r\n\r\n      strings.push_back(text);\r\n   }\r\n\r\n   auto counts = {1000, 10000, 100000, 1000000, 10000000, 100000000};\r\n   for (auto count : counts)\r\n   {\r\n      {\r\n         auto v1 = std::vector&lt;std::string&gt;(std::begin(strings), std::begin(strings) + count);      \r\n         test_v1(v1);\r\n      }\r\n\r\n      {\r\n         auto v2 = std::vector&lt;std::string&gt;(std::begin(strings), std::begin(strings) + count);\r\n         test_v2(v2);\r\n      }\r\n\r\n      {\r\n         auto v3 = std::vector&lt;std::string&gt;(std::begin(strings), std::begin(strings) + count);\r\n         test_v3(v3);\r\n      }\r\n   }\r\n\r\n   return 0;\r\n}<\/pre>\n<p>The results, tested with a 64-bit release build with Visual Studio 2015 Update 2, look like below. Times are in microseconds.<\/p>\n<table border=\"1\">\n<thead>\n<td>No of strings<\/td>\n<td>time v1<\/td>\n<td>time v2<\/td>\n<td>time v3<\/td>\n<td>Percentage of slowdown with v2<\/td>\n<td>Percentage of slowdown with v3<\/td>\n<\/thead>\n<tbody>\n<tr>\n<td>1000<\/td>\n<td>40<\/td>\n<td>57<\/td>\n<td>64<\/td>\n<td>42.5<\/td>\n<td>60<\/td>\n<\/tr>\n<tr>\n<td>10000<\/td>\n<td>593<\/td>\n<td>568<\/td>\n<td>637<\/td>\n<td>42.5<\/td>\n<td>53.1<\/td>\n<\/tr>\n<tr>\n<td>100000<\/td>\n<td>3894<\/td>\n<td>5769<\/td>\n<td>6497<\/td>\n<td>48.2<\/td>\n<td>66.8<\/td>\n<\/tr>\n<tr>\n<td>1000000<\/td>\n<td>40005<\/td>\n<td>57852<\/td>\n<td>65793<\/td>\n<td>44.6<\/td>\n<td>64.5<\/td>\n<\/tr>\n<tr>\n<td>10000000<\/td>\n<td>394573<\/td>\n<td>584048<\/td>\n<td>734463<\/td>\n<td>48<\/td>\n<td>86.1<\/td>\n<\/tr>\n<tr>\n<td>100000000<\/td>\n<td>4298742<\/td>\n<td>6171199<\/td>\n<td>7577972<\/td>\n<td>43.6<\/td>\n<td>76.3<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>I have run this several times with similar results. The following image shows how much slower the versions using <tt>std::back_inserter<\/tt> were comparing with the version that modifies the string directly. With blue it is represented the results for version 2 and with orange the results for version 3 (with initial reservation).<br \/>\n<a href=\"http:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2016\/09\/transform-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2016\/09\/transform-1.png\" alt=\"transform\" width=\"480\" height=\"578\" class=\"alignnone size-full wp-image-2269\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2016\/09\/transform-1.png 480w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2016\/09\/transform-1-249x300.png 249w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<p>This clearly indicates that using <tt>std::back_inserter<\/tt> is slower, and it is actually 30 to 60% slower. However, what has surprized me is that reserving the necessary space for the string before <tt>std::back_inserter<\/tt> starts inserting elements is even slower (in some cases it can take twice as much time than version 1). Of course this measures the time to allocate the buffer too, not just the time for transforming the string, but the point here is to profile the entire function, not just the transform operation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE: For an update on the implementation and the conclusions see A comparison of two std::transform alternatives revisited. I was writing a small utility function to transform a string to uppercase. The obvious solution for that is std::transform, but as I was writing it I realized there are several alternatives: transform an existing string, by &#8230; <a title=\"A comparison of two std::transform alternatives\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/\" aria-label=\"Read more about A comparison of two std::transform alternatives\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[485,486,451,487],"class_list":["post-2258","post","type-post","status-publish","format-standard","hentry","category-c","tag-algorithm","tag-back_inserter","tag-c","tag-transform"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"algorithm,back_inserter,c++,transform\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"A comparison of two std::transform alternatives\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2016-09-07T07:33:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2016-09-12T11:28:17+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"A comparison of two std::transform alternatives\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#article\",\"name\":\"A comparison of two std::transform alternatives\",\"headline\":\"A comparison of two std::transform alternatives\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/09\\\/transform-1.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#articleImage\",\"width\":480,\"height\":578},\"datePublished\":\"2016-09-07T09:33:26+02:00\",\"dateModified\":\"2016-09-12T13:28:17+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":7,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#webpage\"},\"articleSection\":\"C++, algorithm, back_inserter, C++, transform\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#listItem\",\"name\":\"A comparison of two std::transform alternatives\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#listItem\",\"position\":5,\"name\":\"A comparison of two std::transform alternatives\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/\",\"name\":\"A comparison of two std::transform alternatives\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2016\\\/09\\\/07\\\/a-comparison-of-two-stdtransform-alternatives\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2016-09-07T09:33:26+02:00\",\"dateModified\":\"2016-09-12T13:28:17+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"A comparison of two std::transform alternatives","description":"","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/","robots":"max-image-preview:large","keywords":"algorithm,back_inserter,c++,transform","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#article","name":"A comparison of two std::transform alternatives","headline":"A comparison of two std::transform alternatives","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2016\/09\/transform-1.png","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#articleImage","width":480,"height":578},"datePublished":"2016-09-07T09:33:26+02:00","dateModified":"2016-09-12T13:28:17+02:00","inLanguage":"en-US","commentCount":7,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#webpage"},"articleSection":"C++, algorithm, back_inserter, C++, transform"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#listItem","name":"A comparison of two std::transform alternatives"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#listItem","position":5,"name":"A comparison of two std::transform alternatives","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/","name":"A comparison of two std::transform alternatives","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2016-09-07T09:33:26+02:00","dateModified":"2016-09-12T13:28:17+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"A comparison of two std::transform alternatives","og:url":"https:\/\/mariusbancila.ro\/blog\/2016\/09\/07\/a-comparison-of-two-stdtransform-alternatives\/","article:published_time":"2016-09-07T07:33:26+00:00","article:modified_time":"2016-09-12T11:28:17+00:00","twitter:card":"summary","twitter:title":"A comparison of two std::transform alternatives"},"aioseo_meta_data":{"post_id":"2258","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:07:10","updated":"2025-12-12 07:43:26","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":7,"uagb_excerpt":"UPDATE: For an update on the implementation and the conclusions see A comparison of two std::transform alternatives revisited. I was writing a small utility function to transform a string to uppercase. The obvious solution for that is std::transform, but as I was writing it I realized there are several alternatives: transform an existing string, by&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">algorithm<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">back_inserter<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">transform<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">algorithm<\/span>","<span class=\"advgb-post-tax-term\">back_inserter<\/span>","<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">transform<\/span>"]}},"comment_count":"7","relative_dates":{"created":"Posted 10 years ago","modified":"Updated 10 years ago"},"absolute_dates":{"created":"Posted on September 7, 2016","modified":"Updated on September 12, 2016"},"absolute_dates_time":{"created":"Posted on September 7, 2016 9:33 am","modified":"Updated on September 12, 2016 1:28 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-Aq","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=2258"}],"version-history":[{"count":12,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2258\/revisions"}],"predecessor-version":[{"id":2279,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/2258\/revisions\/2279"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=2258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=2258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=2258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}