<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ivan G</title>
    <description>The latest articles on DEV Community by Ivan G (@aloneguid).</description>
    <link>https://dev.to/aloneguid</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F160369%2F6875438f-a860-4a17-b9e4-39f6957b2009.jpeg</url>
      <title>DEV Community: Ivan G</title>
      <link>https://dev.to/aloneguid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aloneguid"/>
    <language>en</language>
    <item>
      <title>Flatten Map Spark Python</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Mon, 15 May 2023 15:38:20 +0000</pubDate>
      <link>https://dev.to/aloneguid/flatten-map-spark-python-1lgh</link>
      <guid>https://dev.to/aloneguid/flatten-map-spark-python-1lgh</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;We have a  &lt;code&gt;DataFrame&lt;/code&gt; with a map property, looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root
 |-- t: timestamp (nullable = true)
 |-- tags: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to transform it to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root
 |-- t: timestamp (nullable = true)
 |-- key1: string
 |-- key2: string
 ...
 |-- keyN: string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;key1...keyN&lt;/code&gt; are all possible combinations of keys in the map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;One of the challenges of working with &lt;code&gt;map&lt;/code&gt; type data is that it does not have a fixed schema. Unlike other types, such as &lt;code&gt;array&lt;/code&gt; or &lt;code&gt;struct&lt;/code&gt;, that have a predefined number and name of columns, &lt;code&gt;map&lt;/code&gt; can have different keys and values for each record. This means that we cannot easily predict how many columns will be generated when we try to flatten a &lt;code&gt;map&lt;/code&gt; type column into multiple columns. For example, if we have a &lt;code&gt;map&lt;/code&gt; column that stores the names and ages of different people, one record might have two keys (&lt;code&gt;name&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt;), while another record might have three keys (&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and &lt;code&gt;gender&lt;/code&gt;). This makes it difficult to process and analyze the data in a consistent way.&lt;/p&gt;

&lt;p&gt;This approach has a limitation: it depends on the current state of the data. If the data changes in the future, the solution might not work anymore. However, this is not a problem for me because I only need to run it once. For those who use Delta Lake, this is also not an issue because Delta Lake can handle schema changes automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get Unique Keys
&lt;/h3&gt;

&lt;p&gt;One of the first steps in data analysis is to identify the unique values or keys in a dataset. This can help us to understand the structure of the data, as well as to create the necessary flat schema.&lt;/p&gt;

&lt;p&gt;The pyspark code for finding the keys in a dataframe is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;map_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tag_keys"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tag_keys"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tag_keys"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;map_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"tag_keys"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;map_keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code operates on a &lt;code&gt;DataFrame&lt;/code&gt; named &lt;code&gt;df&lt;/code&gt; and performs the following operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;select&lt;/code&gt; function is used with the &lt;code&gt;map_keys&lt;/code&gt; transformation from the &lt;code&gt;pyspark.sql.functions&lt;/code&gt; module. It retrieves the keys from the "tags" map column in the &lt;code&gt;DataFrame&lt;/code&gt; &lt;code&gt;df&lt;/code&gt; and renames the resulting column as "tag_keys".&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;explode&lt;/code&gt; function is applied to the "tag_keys" column, which transforms each map key into a separate row, effectively "exploding" the map into multiple rows.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;distinct&lt;/code&gt; function is used to remove any duplicate rows from the &lt;code&gt;DataFrame&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The resulting &lt;code&gt;DataFrame&lt;/code&gt; is assigned to the variable &lt;code&gt;map_keys&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;collect&lt;/code&gt; function is called on the &lt;code&gt;map_keys&lt;/code&gt; &lt;code&gt;DataFrame&lt;/code&gt;, which triggers the execution of the Spark job and returns the results as a list of &lt;code&gt;Row&lt;/code&gt; objects.&lt;/li&gt;
&lt;li&gt;A list comprehension is used to extract the values of the "tag_keys" column from each Row object in the list, and this list of extracted values is assigned back to the variable &lt;code&gt;map_keys&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In summary, this code extracts the distinct keys from a map column named "tags" in the DataFrame &lt;code&gt;df&lt;/code&gt; and stores them as a list of strings in the &lt;code&gt;map_keys&lt;/code&gt; variable. You should get a python array similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'url'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'b_sys_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'bi'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'ua'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'referrer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'out'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'height'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'b_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'profile'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'ppn'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'width'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;'inactive_mins'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One step done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate Flat Schema
&lt;/h3&gt;

&lt;p&gt;To generate flat schema, i'll use python list comprehension again. Honestly, list comprehension is awesome - this is one of the reason I actually started using Python a long time ago. I'm getting of the rails. Ok, the last time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Discover the Magic of Python List Comprehension: Unlocking the Key to Efficiently Generating Flat Schemas. Dive Into the World of Simplified Data Processing in Python and Spark, and Uncover Why List Comprehension Has Been the Secret Ingredient That Made Me Fall in Love With Python Many Years Ago."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back to the topic. Creating flat schema is as easy as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;xdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;df_all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"tags.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;map_keys&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code operates on a &lt;code&gt;DataFrame&lt;/code&gt; named &lt;code&gt;df_all&lt;/code&gt; and performs the following operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;DataFrame&lt;/code&gt; &lt;code&gt;df&lt;/code&gt; is used as the starting point for the transformation. This is our original data.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;*df.columns[:-1]&lt;/code&gt; expression uses the unpacking operator &lt;code&gt;*&lt;/code&gt; to unpack all columns except the last one (&lt;code&gt;[:-1]&lt;/code&gt;) from the &lt;code&gt;df&lt;/code&gt; &lt;code&gt;DataFrame&lt;/code&gt;. This ensures that all columns of &lt;code&gt;df&lt;/code&gt; except the last one are included in the selection, because the last column &lt;code&gt;tags&lt;/code&gt; is the one we don't need to include in the result (we want to flatten it!).&lt;/li&gt;
&lt;li&gt;The expression &lt;code&gt;[f.col(f"tags.{x}") for x in map_keys]&lt;/code&gt; is a list comprehension that generates a list of column expressions dynamically. For each value &lt;code&gt;x&lt;/code&gt; in the &lt;code&gt;map_keys&lt;/code&gt; list, it creates a column expression using &lt;code&gt;f.col(f"tags.{x}")&lt;/code&gt;. This expression accesses the &lt;code&gt;tags&lt;/code&gt; map column in the &lt;code&gt;df&lt;/code&gt; &lt;code&gt;DataFrame&lt;/code&gt; and retrieves the value associated with the key &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The resulting list of column expressions is unpacked using the &lt;code&gt;*&lt;/code&gt; operator within the &lt;code&gt;select&lt;/code&gt; function. This includes the dynamically generated column expressions in the selection alongside the columns from &lt;code&gt;df.columns[:-1]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The resulting &lt;code&gt;DataFrame&lt;/code&gt; is assigned to the variable &lt;code&gt;xdf&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will generate a very wide table (in my case) which looks similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root
 |-- t: timestamp (nullable = true)
 |-- version: string (nullable = true)
 |-- iid: string (nullable = true)
 |-- ip: string (nullable = true)
 |-- event: string (nullable = true)
 |-- user_name: string (nullable = true)
 |-- windows_version: string (nullable = true)
 |-- domain: string (nullable = true)
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything after &lt;code&gt;t&lt;/code&gt; is taken from the map keys.&lt;/p&gt;

&lt;p&gt;And now you can just execute the query and reap the benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix. Why Flattening can be Beneficial
&lt;/h2&gt;

&lt;p&gt;Flattening nested data structures involves transforming a complex nested structure into a &lt;strong&gt;simple one-dimensional list or array&lt;/strong&gt;. This process can be useful for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplifying data access&lt;/strong&gt;: Nested structures can make it challenging to access specific pieces of information. Flattening them makes it easier to &lt;strong&gt;access and manipulate individual data points&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier data processing&lt;/strong&gt;: Flattening a nested structure can &lt;strong&gt;simplify data processing and analysis&lt;/strong&gt; by eliminating the need for complex nested loops or recursion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More efficient storage&lt;/strong&gt;: Storing nested structures can be &lt;strong&gt;memory-intensive&lt;/strong&gt;, and flattening can help &lt;strong&gt;reduce the storage space&lt;/strong&gt; required by eliminating unnecessary levels of nesting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better data visualization&lt;/strong&gt;: Data that is flattened can be more easily &lt;strong&gt;visualized in tables, charts, and graphs&lt;/strong&gt;, which are often one-dimensional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved performance&lt;/strong&gt;: In some cases, flattening can &lt;strong&gt;improve the performance&lt;/strong&gt; of an application by reducing the amount of time and resources required to access and process data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified data integration&lt;/strong&gt;: When working with data from different sources, flattening nested structures can help in &lt;strong&gt;integrating and combining datasets&lt;/strong&gt; more easily. It allows for a consistent format and facilitates merging data based on common attributes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smoother data transformation&lt;/strong&gt;: Flattening nested structures can streamline the process of &lt;strong&gt;data transformation&lt;/strong&gt;. It enables the application of operations and transformations uniformly across the entire dataset, without needing to account for complex nested hierarchies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced compatibility&lt;/strong&gt;: Flattened data structures are often more &lt;strong&gt;compatible with various data analysis and machine learning algorithms&lt;/strong&gt;. Many algorithms require a tabular or flat structure, and by flattening the data, it becomes readily usable for such algorithms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified debugging and troubleshooting&lt;/strong&gt;: Working with flattened data structures can make &lt;strong&gt;debugging and troubleshooting&lt;/strong&gt; easier. It reduces complexity and enables more straightforward identification and resolution of issues related to data quality, consistency, or specific data points.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved data sharing&lt;/strong&gt;: Flattening nested structures can facilitate &lt;strong&gt;data sharing&lt;/strong&gt; with others. It simplifies the process of exchanging data, collaborating on projects, and sharing insights with stakeholders who may not be familiar with complex nested representations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier data export and integration with external systems&lt;/strong&gt;: Flattened data structures are often more compatible and easier to export or integrate with external systems, such as databases, data warehouses, or reporting tools. It simplifies the process of data migration and integration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By flattening nested structures, data becomes more accessible, easier to process, and compatible with a wider range of applications and tools. It promotes simplicity, efficiency, and effective data utilization across various domains and use cases.&lt;/p&gt;

&lt;p&gt;Overall, &lt;strong&gt;flattening nested data structures&lt;/strong&gt; can make working with complex data sets more manageable and efficient.&lt;/p&gt;

&lt;p&gt;By the way, did you know why a data scientist become a pancake chef?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because they loved &lt;strong&gt;flattening data&lt;/strong&gt; almost as much as they loved flattening pancakes! 🥞😄&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.python.org/dev/peps/pep-0448/"&gt;PEP 448 -- Additional Unpacking Generalizations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists"&gt;Python Docs: Unpacking Argument Lists&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PySpark&lt;/code&gt; functions used:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.select.html"&gt;select&lt;/a&gt; - Selects a subset of columns from a DataFrame.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.functions.map_keys.html"&gt;map_keys&lt;/a&gt; - Extracts the keys from a map column.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.Column.alias.html"&gt;alias&lt;/a&gt; - Renames a column.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.select.html"&gt;select&lt;/a&gt; - Selects a subset of columns from a DataFrame.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.functions.map_keys.html"&gt;map_keys&lt;/a&gt; - Extracts the keys from a map column.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.Column.alias.html"&gt;alias&lt;/a&gt; - Renames a column.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>spark</category>
      <category>pyspark</category>
    </item>
    <item>
      <title>Should I use Mongo DB API or Cosmos SQL API in Azure Cosmos DB?</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 30 Mar 2023 15:26:46 +0000</pubDate>
      <link>https://dev.to/aloneguid/should-i-use-mongo-db-api-or-cosmos-sql-api-in-azure-cosmos-db-4gl8</link>
      <guid>https://dev.to/aloneguid/should-i-use-mongo-db-api-or-cosmos-sql-api-in-azure-cosmos-db-4gl8</guid>
      <description>&lt;p&gt;It's a question I asked myself for a long time, so I've decided to answer it for myself and for someone else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Cosmos DB?
&lt;/h2&gt;

&lt;p&gt;Cosmos SQL is a data model within Cosmos DB that supports SQL-like queries against JSON data. It provides a way to store and query structured data in a distributed environment, and it can be a good choice for certain types of applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Model Database.&lt;/strong&gt; Cosmos DB supports multiple data models such as document, key-value, graph, and column-family, allowing developers to use the most appropriate data model for their specific use case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Globally Distributed.&lt;/strong&gt; Cosmos DB provides global distribution of data across multiple regions and zones, with automatic replication and failover capabilities. This allows applications to provide low latency and high availability for users around the world.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Scaling.&lt;/strong&gt; Cosmos DB provides automatic scaling of throughput and storage, based on the needs of the application. This means that as the application grows, Cosmos DB can automatically scale to handle the increased workload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency Levels.&lt;/strong&gt; Cosmos DB provides a range of consistency levels to choose from, allowing developers to balance between data consistency and availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-API Support.&lt;/strong&gt; Cosmos DB supports multiple APIs such as &lt;strong&gt;SQL&lt;/strong&gt;, &lt;strong&gt;MongoDB&lt;/strong&gt;, &lt;strong&gt;Cassandra&lt;/strong&gt;, &lt;strong&gt;Azure Tables&lt;/strong&gt;, and &lt;strong&gt;Gremlin&lt;/strong&gt;, making it easy to use with existing applications and tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security.&lt;/strong&gt; Cosmos DB provides advanced security features such as encryption at rest and in transit, role-based access control, and virtual network integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytics and Visualization.&lt;/strong&gt; Cosmos DB provides built-in analytics and visualization capabilities with Azure Synapse Link, allowing developers to perform real-time analytics on their data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Productivity.&lt;/strong&gt; Cosmos DB provides a range of tools and SDKs to make it easy for developers to get started with the service, including Azure Portal, Azure CLI, Azure PowerShell, and various programming language SDKs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, Cosmos DB provides a comprehensive set of features for building modern, scalable, and highly available applications in the cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I Mix and Match APIs?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Yes and No.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Yes
&lt;/h4&gt;

&lt;p&gt;You can use both SQL and MongoDB APIs in Azure Cosmos DB at the same time. Azure Cosmos DB is designed to be a multi-model database service that supports multiple APIs, including SQL, MongoDB, Cassandra, Azure Table, and Gremlin. This means that you can store data using different data models, and access that data using the appropriate API for your application.&lt;/p&gt;

&lt;p&gt;For example, you could store structured data in a SQL API &lt;strong&gt;container&lt;/strong&gt;, and unstructured data in a MongoDB API &lt;strong&gt;container&lt;/strong&gt; within the same Cosmos DB account. This provides flexibility in how you structure and access your data, while still taking advantage of the benefits of a globally distributed, multi-model database service.&lt;/p&gt;

&lt;h4&gt;
  
  
  No
&lt;/h4&gt;

&lt;p&gt;You cannot use different APIs in the &lt;strong&gt;same container&lt;/strong&gt; in Azure Cosmos DB. &lt;strong&gt;Each container in Cosmos DB is associated with a specific API and data model, and data stored in a container must conform to that data model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, if you create a container using the MongoDB API, you can only store data in that container using the MongoDB data model and API. Similarly, if you create a container using the SQL API, you can only store data in that container using the SQL data model and API.&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;The short answer is &lt;strong&gt;no&lt;/strong&gt;. See expanded answer above. An instance of data is tightly bound to API, and has to be set at the creation time. You cannot change API level later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;When you create&lt;/em&gt; a container in Cosmos DB, you choose a specific API and data model that is associated with that container. The data stored in that container must conform to the data model and API that was chosen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you need to use a different API for your data, you will need to create a new container with the appropriate API and data model&lt;/em&gt;, and then migrate your data to the new container. Depending on the amount of data and the complexity of your application, this migration process can be a complex task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one is Better?
&lt;/h2&gt;

&lt;p&gt;There are some scenarios where using MongoDB in Cosmos DB might be a better choice. One reason is that MongoDB has a more flexible data model than Cosmos SQL. &lt;strong&gt;MongoDB supports nested documents and arrays&lt;/strong&gt;, which can be more difficult to model in Cosmos SQL. Additionally, MongoDB has a &lt;strong&gt;richer set of query operators and aggregation functions&lt;/strong&gt;, which can make it easier to work with complex data.&lt;/p&gt;

&lt;p&gt;Another reason to use MongoDB in Cosmos DB is if you're already using MongoDB in your application and want to take advantage of Cosmos DB's global distribution, low latency, and automatic scaling features. By using the MongoDB API in Cosmos DB, you can continue to use the same MongoDB drivers and tools that you're already familiar with, while also gaining the benefits of Cosmos DB's global distribution and scalability.&lt;/p&gt;

&lt;p&gt;Ultimately, the choice between using Cosmos SQL or MongoDB in Cosmos DB depends on your specific application requirements and data model. You should evaluate both options to determine which one is the best fit for your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  In Layman's Terms, Which One Should I Go For?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Short Answer
&lt;/h3&gt;

&lt;p&gt;MongoDB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long Answer
&lt;/h3&gt;

&lt;p&gt;It depends :) See feature comparison table below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SQL API&lt;/th&gt;
&lt;th&gt;MongoDB API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tabular, column-family&lt;/td&gt;
&lt;td&gt;Document-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Query Language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQL-like&lt;/td&gt;
&lt;td&gt;Document-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supports indexing on specific columns&lt;/td&gt;
&lt;td&gt;Supports indexing on fields within documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transactions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supports multi-document transactions&lt;/td&gt;
&lt;td&gt;Supports single-document transactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Provides strong consistency by default&lt;/td&gt;
&lt;td&gt;Provides eventual consistency by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Highly scalable, distributed database&lt;/td&gt;
&lt;td&gt;Highly scalable, distributed database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Programming Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Similar to traditional relational databases&lt;/td&gt;
&lt;td&gt;Optimized for working with JSON documents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cosmos SQL
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Azure Portal.&lt;/strong&gt; The Azure Portal provides a web-based interface for managing and querying data in Cosmos DB. However, it honestly feels clunky and is only suitable for very simple ad-hoc queries.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=SavranWeb.cosmosdbsqlapi"&gt;Cosmos DB SQL Studio&lt;/a&gt;. Very simple unofficial extension for VS Code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sachabruttin/CosmosDbExplorer"&gt;Cosmos DB Explorer&lt;/a&gt;. A promising Windows Desktop application, however I found it crashing often and in general really unstable. And it's Windows-only.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a developer who works with Cosmos DB, I have faced many challenges and frustrations with the lack of proper tools for this database service. It's worth noting I have tried really hard to find a good tool for Cosmos DB. There are none, even official ones. And it's been a while since it exists.&lt;/p&gt;

&lt;p&gt;These limitations are not insurmountable, but they require extra work and code to overcome. And this is where a good tool for Cosmos DB would come in handy. &lt;/p&gt;

&lt;p&gt;Unfortunately, such a tool does not exist yet. The official tools provided by Microsoft are either outdated, incomplete, or buggy. For example, the Azure portal only supports the SQL API and has a limited UI for browsing and querying data. The Azure Data Studio extension only supports the MongoDB API and has a poor performance and user experience. The Azure Cosmos DB Emulator only works on Windows and does not support all the features of the service.&lt;/p&gt;

&lt;p&gt;Therefore, I think there is a huge gap in the market for a good tool for Cosmos DB. A tool that would make the life of developers easier and more productive. A tool that would leverage the full potential of Cosmos DB and help to create better applications. A tool that would be updated regularly and supported by a dedicated team.&lt;/p&gt;

&lt;p&gt;If you are a developer who works with Cosmos DB, or if you are interested in creating such a tool, please let me know. I would love to hear your thoughts and feedback on this topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mongo
&lt;/h3&gt;

&lt;p&gt;There are &lt;strong&gt;hundreds&lt;/strong&gt; of developer tools available for working with MongoDB, depending on your preferences and development environment. Here are some popular ones:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB Compass.&lt;/strong&gt; A graphical user interface for MongoDB. &lt;a href="https://www.mongodb.com/products/compass"&gt;https://www.mongodb.com/products/compass&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robo 3T&lt;/strong&gt;. A lightweight, open-source MongoDB GUI client. &lt;a href="https://robomongo.org/"&gt;https://robomongo.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Studio 3T&lt;/strong&gt;. A comprehensive MongoDB GUI client with advanced features such as SQL support, aggregation pipeline builders, and query autocompletion. &lt;a href="https://studio3t.com/"&gt;https://studio3t.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NoSQLBooster for MongoDB&lt;/strong&gt;. A smart GUI client for MongoDB with features such as IntelliShell, visual query builder, and schema analyzer. &lt;a href="https://nosqlbooster.com/"&gt;https://nosqlbooster.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aqua Data Studio&lt;/strong&gt;: A multi-platform database IDE that supports MongoDB, with features such as visual analytics, data import/export, and SQL debugging. From the maker of Cosmos DB but with no Cosmos SQL support :)  &lt;a href="https://www.aquadatastudio.com/"&gt;https://www.aquadatastudio.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navicat for MongoDB.&lt;/strong&gt; A GUI tool for managing MongoDB databases with features such as data modeling, data synchronization, and query building. &lt;a href="https://www.navicat.com/en/products/navicat-for-mongodb"&gt;https://www.navicat.com/en/products/navicat-for-mongodb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datagrip.&lt;/strong&gt; A multi-platform database IDE that supports MongoDB, with features such as code completion, code analysis, and schema editor. &lt;a href="https://www.jetbrains.com/datagrip/"&gt;https://www.jetbrains.com/datagrip/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are just a few examples of the many developer tools available for working with MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;It's difficult to compare the average prices of Cosmos DB with SQL API and Mongo API directly because the pricing model for Cosmos DB is based on several factors including the choice of API, data storage, throughput, and regions. However, here are some factors to consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data storage: Both SQL API and Mongo API use the same pricing model for data storage in Cosmos DB, which is based on the amount of data stored per month. The price per GB of data stored is the same regardless of which API is used.&lt;/li&gt;
&lt;li&gt;Request units: Request units (RUs) are a measure of the throughput capacity of a Cosmos DB database. Both SQL API and Mongo API use the same pricing model for RUs. The cost of RUs varies depending on the performance level chosen, which is based on the number of RUs per second required for your application.&lt;/li&gt;
&lt;li&gt;Regions: The cost of using Cosmos DB also depends on the number of regions selected for your deployment. Each region has its own pricing, so the more regions you select, the higher the cost.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In general, the cost of using SQL API and Mongo API in Cosmos DB will depend on the specific requirements of your application and the amount of data storage and throughput required. It's important to carefully consider your application's needs and compare pricing options before choosing an API.&lt;/p&gt;

&lt;p&gt;Verdict - mostly equal.&lt;/p&gt;

</description>
      <category>msazure</category>
      <category>cosmosdb</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Is It Faster to Enumerate an Array With "foreach" or "for" in C#?</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 22 Dec 2022 10:10:47 +0000</pubDate>
      <link>https://dev.to/aloneguid/is-it-faster-to-enumerate-an-array-with-foreach-or-for-in-c-334p</link>
      <guid>https://dev.to/aloneguid/is-it-faster-to-enumerate-an-array-with-foreach-or-for-in-c-334p</guid>
      <description>&lt;p&gt;Here's an interesting question - having an array of integers, is it faster to enumerate it, to perform a simple operation on an element, with &lt;code&gt;for&lt;/code&gt; or &lt;code&gt;foreach&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;To answer this, first of all I've created a benchmark that covers 3 use cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;for&lt;/code&gt; loop and get an element by it's index.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;foreach&lt;/code&gt; on the array.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;foreach&lt;/code&gt; on the array, but before enumerating case the array to &lt;code&gt;IEnumerable&lt;/code&gt; forcibly. I don't know why I had a hunch that might behave slightly different, but I did it anyway.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the testing code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;LINQPad&lt;/span&gt; &lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;+&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AutoScrollResults&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;BenchmarkRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Enumeration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ShortRunJob&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MinColumn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MaxColumn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MeanColumn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MedianColumn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MemoryDiagnoser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MarkdownExporter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Enumeration&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;_source&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;GlobalSetup&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;EnumerateAsArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_source&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;EnumerateWithForeach&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;EnumerateWithForeachAfterCasting&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;_source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Length&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;StdDev&lt;/th&gt;
&lt;th&gt;Min&lt;/th&gt;
&lt;th&gt;Max&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;th&gt;Gen0&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateAsArray&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;3.473 ns&lt;/td&gt;
&lt;td&gt;1.4879 ns&lt;/td&gt;
&lt;td&gt;0.0816 ns&lt;/td&gt;
&lt;td&gt;3.385 ns&lt;/td&gt;
&lt;td&gt;3.546 ns&lt;/td&gt;
&lt;td&gt;3.490 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeach&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;3.081 ns&lt;/td&gt;
&lt;td&gt;0.6979 ns&lt;/td&gt;
&lt;td&gt;0.0383 ns&lt;/td&gt;
&lt;td&gt;3.057 ns&lt;/td&gt;
&lt;td&gt;3.125 ns&lt;/td&gt;
&lt;td&gt;3.062 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeachAfterCasting&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;360.151 ns&lt;/td&gt;
&lt;td&gt;112.8064 ns&lt;/td&gt;
&lt;td&gt;6.1833 ns&lt;/td&gt;
&lt;td&gt;353.018 ns&lt;/td&gt;
&lt;td&gt;363.983 ns&lt;/td&gt;
&lt;td&gt;363.452 ns&lt;/td&gt;
&lt;td&gt;0.0648&lt;/td&gt;
&lt;td&gt;272 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateAsArray&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;49.681 ns&lt;/td&gt;
&lt;td&gt;10.2353 ns&lt;/td&gt;
&lt;td&gt;0.5610 ns&lt;/td&gt;
&lt;td&gt;49.237 ns&lt;/td&gt;
&lt;td&gt;50.311 ns&lt;/td&gt;
&lt;td&gt;49.495 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeach&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;42.489 ns&lt;/td&gt;
&lt;td&gt;15.0294 ns&lt;/td&gt;
&lt;td&gt;0.8238 ns&lt;/td&gt;
&lt;td&gt;41.728 ns&lt;/td&gt;
&lt;td&gt;43.364 ns&lt;/td&gt;
&lt;td&gt;42.375 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeachAfterCasting&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;3,365.735 ns&lt;/td&gt;
&lt;td&gt;1,017.7344 ns&lt;/td&gt;
&lt;td&gt;55.7855 ns&lt;/td&gt;
&lt;td&gt;3,330.609 ns&lt;/td&gt;
&lt;td&gt;3,430.059 ns&lt;/td&gt;
&lt;td&gt;3,336.535 ns&lt;/td&gt;
&lt;td&gt;0.5798&lt;/td&gt;
&lt;td&gt;2432 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateAsArray&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;404.754 ns&lt;/td&gt;
&lt;td&gt;101.6160 ns&lt;/td&gt;
&lt;td&gt;5.5699 ns&lt;/td&gt;
&lt;td&gt;399.244 ns&lt;/td&gt;
&lt;td&gt;410.382 ns&lt;/td&gt;
&lt;td&gt;404.638 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeach&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;366.522 ns&lt;/td&gt;
&lt;td&gt;44.1604 ns&lt;/td&gt;
&lt;td&gt;2.4206 ns&lt;/td&gt;
&lt;td&gt;364.396 ns&lt;/td&gt;
&lt;td&gt;369.157 ns&lt;/td&gt;
&lt;td&gt;366.015 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeachAfterCasting&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;34,436.210 ns&lt;/td&gt;
&lt;td&gt;16,553.4298 ns&lt;/td&gt;
&lt;td&gt;907.3493 ns&lt;/td&gt;
&lt;td&gt;33,513.147 ns&lt;/td&gt;
&lt;td&gt;35,326.984 ns&lt;/td&gt;
&lt;td&gt;34,468.500 ns&lt;/td&gt;
&lt;td&gt;5.7373&lt;/td&gt;
&lt;td&gt;24032 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateAsArray&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;4,011.964 ns&lt;/td&gt;
&lt;td&gt;1,402.6901 ns&lt;/td&gt;
&lt;td&gt;76.8862 ns&lt;/td&gt;
&lt;td&gt;3,924.527 ns&lt;/td&gt;
&lt;td&gt;4,069.007 ns&lt;/td&gt;
&lt;td&gt;4,042.358 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeach&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;3,644.260 ns&lt;/td&gt;
&lt;td&gt;350.8573 ns&lt;/td&gt;
&lt;td&gt;19.2317 ns&lt;/td&gt;
&lt;td&gt;3,632.706 ns&lt;/td&gt;
&lt;td&gt;3,666.461 ns&lt;/td&gt;
&lt;td&gt;3,633.613 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeachAfterCasting&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;td&gt;340,725.798 ns&lt;/td&gt;
&lt;td&gt;170,058.5539 ns&lt;/td&gt;
&lt;td&gt;9,321.4832 ns&lt;/td&gt;
&lt;td&gt;330,179.199 ns&lt;/td&gt;
&lt;td&gt;347,861.084 ns&lt;/td&gt;
&lt;td&gt;344,137.109 ns&lt;/td&gt;
&lt;td&gt;57.1289&lt;/td&gt;
&lt;td&gt;240033 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateAsArray&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;40,460.423 ns&lt;/td&gt;
&lt;td&gt;9,494.4089 ns&lt;/td&gt;
&lt;td&gt;520.4206 ns&lt;/td&gt;
&lt;td&gt;40,090.979 ns&lt;/td&gt;
&lt;td&gt;41,055.597 ns&lt;/td&gt;
&lt;td&gt;40,234.692 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeach&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;36,107.100 ns&lt;/td&gt;
&lt;td&gt;6,022.3198 ns&lt;/td&gt;
&lt;td&gt;330.1037 ns&lt;/td&gt;
&lt;td&gt;35,901.172 ns&lt;/td&gt;
&lt;td&gt;36,487.848 ns&lt;/td&gt;
&lt;td&gt;35,932.281 ns&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EnumerateWithForeachAfterCasting&lt;/td&gt;
&lt;td&gt;100000&lt;/td&gt;
&lt;td&gt;3,892,458.333 ns&lt;/td&gt;
&lt;td&gt;4,019,109.7373 ns&lt;/td&gt;
&lt;td&gt;220,300.9666 ns&lt;/td&gt;
&lt;td&gt;3,652,532.422 ns&lt;/td&gt;
&lt;td&gt;4,085,627.734 ns&lt;/td&gt;
&lt;td&gt;3,939,214.844 ns&lt;/td&gt;
&lt;td&gt;570.3125&lt;/td&gt;
&lt;td&gt;2400038 B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The findings are impressive - enumerating an &lt;strong&gt;array&lt;/strong&gt; with &lt;code&gt;for&lt;/code&gt; or &lt;code&gt;foreach&lt;/code&gt; is not much different, but surprisingly &lt;code&gt;foreach&lt;/code&gt; is slightly faster (around 12%). Whereas when casting to &lt;code&gt;IEnumerable&lt;/code&gt; and then performing iteration is way way slower than anything else! In fact, it's about 107 times slower than normal array iteration!&lt;/p&gt;

&lt;p&gt;To understand what's happening, I'm going to disassembly the generated code.&lt;/p&gt;

&lt;h2&gt;
  
  
  EnumerateAsArray
&lt;/h2&gt;

&lt;p&gt;This is IL representation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IL_0000  ldc.i4.0   
IL_0001  stloc.0     // count 
IL_0002  ldc.i4.0   
IL_0003  stloc.1     // i 
IL_0004  br.s  IL_0017 
IL_0006  ldarg.0   
IL_0007  ldfld  Enumeration._source 
IL_000C  ldloc.1     // i 
IL_000D  ldelem.i4   
IL_000E  pop   
IL_000F  ldloc.0     // count 
IL_0010  ldc.i4.1   
IL_0011  add   
IL_0012  stloc.0     // count 
IL_0013  ldloc.1     // i 
IL_0014  ldc.i4.1   
IL_0015  add   
IL_0016  stloc.1     // i 
IL_0017  ldloc.1     // i 
IL_0018  ldarg.0   
IL_0019  ldfld  Enumeration.Length 
IL_001E  blt.s  IL_0006 
IL_0020  ret  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this is what's happening:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create two variables - &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep comparing array length to &lt;code&gt;i&lt;/code&gt; (IL_0017). When &lt;code&gt;i&lt;/code&gt; is less than array length, jump to IL_0006.&lt;/li&gt;
&lt;li&gt;Load array element.&lt;/li&gt;
&lt;li&gt;Increment the count.&lt;/li&gt;
&lt;li&gt;Increment &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  EnumerateWithForeach
&lt;/h2&gt;

&lt;p&gt;IL source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IL_0000  ldc.i4.0   
IL_0001  stloc.0     // count 
IL_0002  ldarg.0   
IL_0003  ldfld  Enumeration._source 
IL_0008  stloc.1   
IL_0009  ldc.i4.0   
IL_000A  stloc.2   
IL_000B  br.s  IL_0019 
IL_000D  ldloc.1   
IL_000E  ldloc.2   
IL_000F  ldelem.i4   
IL_0010  pop   
IL_0011  ldloc.0     // count 
IL_0012  ldc.i4.1   
IL_0013  add   
IL_0014  stloc.0     // count 
IL_0015  ldloc.2   
IL_0016  ldc.i4.1   
IL_0017  add   
IL_0018  stloc.2   
IL_0019  ldloc.2   
IL_001A  ldloc.1   
IL_001B  ldlen   
IL_001C  conv.i4   
IL_001D  blt.s  IL_000D 
IL_001F  ret  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not much different to before, but .NET runtime makes slight optimisation, because it knows you are going to need to value and not need the index (&lt;code&gt;foreach&lt;/code&gt; always retrieves the value). So that's good!&lt;/p&gt;

&lt;h2&gt;
  
  
  EnumerateWithForeachAfterCasting
&lt;/h2&gt;

&lt;p&gt;IL source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IL_0000  ldc.i4.0   
IL_0001  stloc.0     // count 
IL_0002  ldarg.0   
IL_0003  ldfld  Enumeration._source 
IL_0008  callvirt  IEnumerable.GetEnumerator () 
IL_000D  stloc.1   
IL_000E  br.s  IL_0020 
IL_0010  ldloc.1   
IL_0011  callvirt  IEnumerator.get_Current () 
IL_0016  unbox.any  Int32 
IL_001B  pop   
IL_001C  ldloc.0     // count 
IL_001D  ldc.i4.1   
IL_001E  add   
IL_001F  stloc.0     // count 
IL_0020  ldloc.1   
IL_0021  callvirt  IEnumerator.MoveNext () 
IL_0026  brtrue.s  IL_0010 
IL_0028  leave.s  IL_003B 
IL_002A  ldloc.1   
IL_002B  isinst  IDisposable 
IL_0030  stloc.2   
IL_0031  ldloc.2   
IL_0032  brfalse.s  IL_003A 
IL_0034  ldloc.2   
IL_0035  callvirt  IDisposable.Dispose () 
IL_003A  endfinally   
IL_003B  ret  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow! You don't need to be an IL expect to see this will be slow, because it's full of &lt;code&gt;callvirt&lt;/code&gt; calls. Calling virtual methods is expensive! This time &lt;strong&gt;you&lt;/strong&gt; are forcing C# to use &lt;code&gt;IEnumerable&lt;/code&gt; pattern, and that's exactly what it does. To represent this code in C# 1, it translates to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;_source&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt; &lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MoveNext&lt;/span&gt; &lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;enumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IDisposable&lt;/span&gt; &lt;span class="n"&gt;disposable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enumerator&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disposable&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;disposable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt; &lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a lot of method calls and unboxing, all are extremely expensive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6e3czl0whzbi2313ey6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6e3czl0whzbi2313ey6.png" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;If you can, prefer &lt;code&gt;foreach&lt;/code&gt; to &lt;code&gt;for&lt;/code&gt; loops, they will be slightly faster.&lt;/li&gt;
&lt;li&gt;Never cast arrays to &lt;code&gt;IEnumerable&lt;/code&gt; and then enumerate, as this expands into a lot of virtual calls using &lt;code&gt;IEnumerator&lt;/code&gt; pattern.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>csharp</category>
      <category>performance</category>
    </item>
    <item>
      <title>Install .NET 6 runtime on clean Alpine Linux</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Fri, 23 Sep 2022 11:45:18 +0000</pubDate>
      <link>https://dev.to/aloneguid/install-net-6-runtime-on-clean-alpine-linux-bn7</link>
      <guid>https://dev.to/aloneguid/install-net-6-runtime-on-clean-alpine-linux-bn7</guid>
      <description>&lt;p&gt;These are step-by-step instructions as they seems to be scattered all over the internet. I will start with a completely clean, stock Alpine distro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;Alpine does not have .NET 6 installers or sudo, so you have to install dependencies as admin first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;isb:/home/alg# apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz
&lt;span class="o"&gt;(&lt;/span&gt;1/13&lt;span class="o"&gt;)&lt;/span&gt; Installing ncurses-terminfo-base &lt;span class="o"&gt;(&lt;/span&gt;6.3_p20211120-r1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;2/13&lt;span class="o"&gt;)&lt;/span&gt; Installing ncurses-libs &lt;span class="o"&gt;(&lt;/span&gt;6.3_p20211120-r1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;3/13&lt;span class="o"&gt;)&lt;/span&gt; Installing readline &lt;span class="o"&gt;(&lt;/span&gt;8.1.1-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;4/13&lt;span class="o"&gt;)&lt;/span&gt; Installing bash &lt;span class="o"&gt;(&lt;/span&gt;5.1.16-r0&lt;span class="o"&gt;)&lt;/span&gt;
Executing bash-5.1.16-r0.post-install
&lt;span class="o"&gt;(&lt;/span&gt;5/13&lt;span class="o"&gt;)&lt;/span&gt; Installing libgcc &lt;span class="o"&gt;(&lt;/span&gt;10.3.1_git20211027-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;6/13&lt;span class="o"&gt;)&lt;/span&gt; Installing libstdc++ &lt;span class="o"&gt;(&lt;/span&gt;10.3.1_git20211027-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;7/13&lt;span class="o"&gt;)&lt;/span&gt; Installing icu-libs &lt;span class="o"&gt;(&lt;/span&gt;69.1-r1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;8/13&lt;span class="o"&gt;)&lt;/span&gt; Installing krb5-conf &lt;span class="o"&gt;(&lt;/span&gt;1.0-r2&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;9/13&lt;span class="o"&gt;)&lt;/span&gt; Installing libcom_err &lt;span class="o"&gt;(&lt;/span&gt;1.46.4-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;10/13&lt;span class="o"&gt;)&lt;/span&gt; Installing keyutils-libs &lt;span class="o"&gt;(&lt;/span&gt;1.6.3-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;11/13&lt;span class="o"&gt;)&lt;/span&gt; Installing libverto &lt;span class="o"&gt;(&lt;/span&gt;0.3.2-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;12/13&lt;span class="o"&gt;)&lt;/span&gt; Installing krb5-libs &lt;span class="o"&gt;(&lt;/span&gt;1.19.3-r0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;13/13&lt;span class="o"&gt;)&lt;/span&gt; Installing libintl &lt;span class="o"&gt;(&lt;/span&gt;0.21-r0&lt;span class="o"&gt;)&lt;/span&gt;
Executing busybox-1.34.1-r3.trigger
OK: 49 MiB &lt;span class="k"&gt;in &lt;/span&gt;35 packages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  .NET 6
&lt;/h3&gt;

&lt;p&gt;.NET 6 itself does not need admin privileges to install. First, download install script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;isb:~&lt;span class="nv"&gt;$ &lt;/span&gt;wget https://dot.net/v1/dotnet-install.sh
Connecting to dot.net &lt;span class="o"&gt;(&lt;/span&gt;20.84.181.62:443&lt;span class="o"&gt;)&lt;/span&gt;
Connecting to dotnet.microsoft.com &lt;span class="o"&gt;(&lt;/span&gt;13.107.246.64:443&lt;span class="o"&gt;)&lt;/span&gt;
saving to &lt;span class="s1"&gt;'dotnet-install.sh'&lt;/span&gt;
dotnet-install.sh    100% |&lt;span class="k"&gt;************************************************************************&lt;/span&gt;| 57823  0:00:00 ETA
&lt;span class="s1"&gt;'dotnet-install.sh'&lt;/span&gt; saved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;give it exec permission&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;isb:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x dotnet-install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and install the latest runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;isb:~&lt;span class="nv"&gt;$ &lt;/span&gt;./dotnet-install.sh &lt;span class="nt"&gt;-c&lt;/span&gt; Current &lt;span class="nt"&gt;--runtime&lt;/span&gt; aspnetcore
dotnet-install: Note that the intended use of this script is &lt;span class="k"&gt;for &lt;/span&gt;Continuous Integration &lt;span class="o"&gt;(&lt;/span&gt;CI&lt;span class="o"&gt;)&lt;/span&gt; scenarios, where:
dotnet-install: - The SDK needs to be installed without user interaction and without admin rights.
dotnet-install: - The SDK installation doesn&lt;span class="s1"&gt;'t need to persist across multiple CI runs.
dotnet-install: To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.

dotnet-install: wget extra options are unavailable for this environment
dotnet-install: Attempting to download using aka.ms link https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.9/aspnetcore-runtime-6.0.9-linux-musl-x64.tar.gz
dotnet-install: wget extra options are unavailable for this environment
Connecting to dotnetcli.azureedge.net (152.199.19.161:443)
saving to '&lt;/span&gt;/tmp/dotnet.XXXKEaFfa&lt;span class="s1"&gt;'
dotnet.XXXKEaFfa     100% |************************************************************************| 37.5M  0:00:00 ETA
'&lt;/span&gt;/tmp/dotnet.XXXKEaFfa&lt;span class="s1"&gt;' saved
dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/6.0.9/aspnetcore-runtime-6.0.9-linux-musl-x64.tar.gz
dotnet-install: Installed version is 6.0.9
dotnet-install: Adding to current process PATH: `/home/alg/.dotnet`. Note: This change will be visible only when sourcing script.
dotnet-install: Note that the script does not resolve dependencies during installation.
dotnet-install: To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the "Dependencies" section.
dotnet-install: Installation finished successfully.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point .net is fully installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add to path
&lt;/h3&gt;

&lt;p&gt;Alpine is using &lt;strong&gt;ash&lt;/strong&gt; shell, so you need to create &lt;code&gt;.profile&lt;/code&gt; in your home folder and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DOTNET_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/.dotnet
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$DOTNET_ROOT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now reload the shell and you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short way
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run as su
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su
apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib
&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run as user
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://dot.net/v1/dotnet-install.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x dotnet-install.sh
./dotnet-install.sh &lt;span class="nt"&gt;-c&lt;/span&gt; Current &lt;span class="nt"&gt;--runtime&lt;/span&gt; aspnetcore
vi .profile
&lt;span class="c"&gt;# paste 2 lines:&lt;/span&gt;
&lt;span class="c"&gt;# export DOTNET_ROOT=$(pwd)/.dotnet&lt;/span&gt;
&lt;span class="c"&gt;# export PATH=$PATH:$DOTNET_ROOT&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; .profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>alpine</category>
      <category>linux</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Stress Testing with cURL</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 15 Sep 2022 12:06:11 +0000</pubDate>
      <link>https://dev.to/aloneguid/stress-testing-with-curl-5818</link>
      <guid>https://dev.to/aloneguid/stress-testing-with-curl-5818</guid>
      <description>&lt;p&gt;There are plenty of tools for stress testing, read &lt;a href="https://rapidapi.com/products/api-testing/"&gt;RapidAPI&lt;/a&gt;, &lt;a href="https://paw.cloud/"&gt;paw&lt;/a&gt;, &lt;a href="https://www.soapui.org/"&gt;SoapUI&lt;/a&gt;, &lt;a href="https://www.postman.com/"&gt;Postman&lt;/a&gt;, &lt;a href="https://rest-assured.io/"&gt;rest-assured&lt;/a&gt;, &lt;a href="https://jmeter.apache.org/"&gt;JMeter&lt;/a&gt; and so on! I'm sure they are amazing, however that's all big and heavy, slow, sometimes paid tools!&lt;/p&gt;

&lt;p&gt;If all you need is just simple (or not, depending on what you want) stress testing, &lt;a href="https://curl.se/"&gt;cURL&lt;/a&gt; is your hidden gem! cURL works pretty much everywhere, and even Windows has curl installed &lt;a href="https://docs.microsoft.com/en-us/virtualization/community/team-blog/2017/20171219-tar-and-curl-come-to-windows"&gt;out of the box&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;To remind, to issue a simple cURL request, just issue it like &lt;code&gt;curl http://localhost/path1&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  A bit more
&lt;/h2&gt;

&lt;p&gt;What if you need to test path1, path2 and path3? Easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost/path&lt;span class="o"&gt;{&lt;/span&gt;1,2,3&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that will issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost/path1
http://localhost/path2
http://localhost/path3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that can be also replaced with &lt;code&gt;curl http://localhost/path[1-3]&lt;/code&gt; to the same effect, i.e. you can use ranges!&lt;/p&gt;

&lt;p&gt;Ranges can be mixed i.e.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost/path&lt;span class="o"&gt;{&lt;/span&gt;1,2,3&lt;span class="o"&gt;}&lt;/span&gt;/subpath[1-3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will issue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost/path1/subpath1
http://localhost/path1/subpath2
http://localhost/path1/subpath3
http://localhost/path2/subpath1
http://localhost/path2/subpath2
http://localhost/path2/subpath3
http://localhost/path3/subpath1
http://localhost/path3/subpath2
http://localhost/path3/subpath3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can also use letters i.e. &lt;code&gt;http://localhost/path-[a-z]&lt;/code&gt; will issue queries from &lt;code&gt;http://localhost/path-a&lt;/code&gt; to &lt;code&gt;http://localhost/path-z&lt;/code&gt; (26 requests total).&lt;/p&gt;

&lt;p&gt;That is already cool!&lt;/p&gt;

&lt;p&gt;All the requests are executed &lt;strong&gt;sequentially&lt;/strong&gt; so if that's ok with you (and most of the times it is) you should be fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serious offense
&lt;/h2&gt;

&lt;p&gt;Ok, what about a parallel load? &lt;a href="https://linuxconfig.org/xargs-for-beginners-with-examples"&gt;&lt;code&gt;xargs&lt;/code&gt;&lt;/a&gt; will come to rescue! Specifically the &lt;a href="https://linuxconfig.org/multi-threaded-xargs-with-examples"&gt;multi-threaded version&lt;/a&gt;. As you should know, &lt;code&gt;xargs&lt;/code&gt; (stands for &lt;em&gt;extended arguments&lt;/em&gt;) allows to fork execution from an input to an execution per line. Combined with &lt;a href="https://www.howtogeek.com/693549/how-to-use-the-seq-command-on-linux/"&gt;&lt;code&gt;seq&lt;/code&gt;&lt;/a&gt; you can start an offensive 😜&lt;code&gt;seq&lt;/code&gt; can generate input you want (numbers only) i.e. &lt;code&gt;seq 1 5&lt;/code&gt; will produce 5 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
2
3
4
5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then piping this into &lt;code&gt;xargs&lt;/code&gt; allows 5 executions i.e. &lt;code&gt;seq 1 5 | xargs -I{} curl http://localhost/path{}&lt;/code&gt; will invoke sequentially:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost/path1
http://localhost/path2
http://localhost/path3
http://localhost/path4
http://localhost/path5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but passing &lt;code&gt;-P&lt;/code&gt; will allow you to paralellise requests! So this is how you issue 500 requests with 5 always going in parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 500 | xargs &lt;span class="nt"&gt;-P5&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; curl http://localhost/path&lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to absolutely exhaust the target, pass a higher number into &lt;code&gt;-P&lt;/code&gt;, or to max it out pass &lt;code&gt;0&lt;/code&gt; as parallelism. From official man pages:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If max-procs is 0, xargs will run  as  many processes  as  possible  at  a time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You do lose some ability of more powerful cURL ranges, especially with characters, as &lt;code&gt;seq&lt;/code&gt; only produces numbers. However even this can be fixed. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;seq&lt;/code&gt; supports &lt;code&gt;-f&lt;/code&gt; switch allowing you to pass a custom format string, however that's not very useful because you are already formatting with &lt;code&gt;xargs&lt;/code&gt; (&lt;code&gt;-I{}&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;You can do even better - generate a lot of word permutations! Take &lt;code&gt;crunch&lt;/code&gt; for example (may need to install it i.e. &lt;code&gt;apt install crunch&lt;/code&gt;) and generate words 5 character length:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crunch 5 5 &lt;span class="nt"&gt;-o&lt;/span&gt; 5words.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file is quite large (67mb) and takes a few seconds to generate, hence we save it locally. Then take this "dictionary" as an input of a stress test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;5words.txt | xargs &lt;span class="nt"&gt;-n1&lt;/span&gt; &lt;span class="nt"&gt;-P5&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; curl http://localhost/words/&lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will issue 11881376 (11 million!) requests in parallel! More than enough if you ask me. &lt;/p&gt;

&lt;p&gt;So is there a need for a dedicated stress tool? I don't think so.&lt;/p&gt;

&lt;h3&gt;
  
  
  PowerShell Friends
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Parallel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;http://localhost/path&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;1..10&lt;/code&gt; is a "range operator", equivalent to &lt;code&gt;seq 1 10&lt;/code&gt; (at least something is shorter in PS ;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;%&lt;/code&gt; is an alias for &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7.2"&gt;&lt;code&gt;Foreach-Object&lt;/code&gt;&lt;/a&gt; which can run in parallel mode optionally.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-Parallel&lt;/code&gt; flag is only available in PowerShell 7 and higher. One can use &lt;code&gt;-ThrottleLimit&lt;/code&gt; parameter to further limit number of parallel "threads", otherwise it's unlimited (equivalent to &lt;code&gt;xargs&lt;/code&gt;' &lt;code&gt;-P&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ranges in PowerShell&lt;/strong&gt; can also do letters, but it's not obvious - &lt;code&gt;[char]'a'..[char]'z'&lt;/code&gt; will produce&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do a &lt;em&gt;reverse range&lt;/em&gt; by doing &lt;code&gt;5..1&lt;/code&gt; which produces&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5
4
3
2
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>bash</category>
      <category>powershell</category>
      <category>curl</category>
    </item>
    <item>
      <title>Scala Mind Map</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 14 Jul 2022 11:16:00 +0000</pubDate>
      <link>https://dev.to/aloneguid/scala-mind-map-292h</link>
      <guid>https://dev.to/aloneguid/scala-mind-map-292h</guid>
      <description>&lt;p&gt;This post has no words but mostly a mind map I've created over years when learning Scala. It's serves as a quick reminder for majority of Scala features. You can zoom it indefinitely thanks for it being exported in SVG.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.aloneguid.uk/posts/2022/05/scala-mind-map/map.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qf-4EksD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03pjp8ozupaw2947l207.png" alt="map" width="880" height="1317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S. Watch &lt;a href="https://www.aloneguid.uk/posts/2022/05/scala-mind-map/"&gt;this page&lt;/a&gt; for further updates.&lt;/p&gt;

</description>
      <category>scala</category>
      <category>mindmap</category>
    </item>
    <item>
      <title>Face Detection with OpenCV (for complete Dummies)</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Wed, 23 Mar 2022 15:59:50 +0000</pubDate>
      <link>https://dev.to/aloneguid/face-detection-with-opencv-for-complete-dummies-19jo</link>
      <guid>https://dev.to/aloneguid/face-detection-with-opencv-for-complete-dummies-19jo</guid>
      <description>&lt;p&gt;This is a very dumb and straightforward tutorial that is meant to be a complete newbie intro into face detection. I'll be using &lt;a href="https://opencv.org/"&gt;OpenCV&lt;/a&gt; for this, and python for simplicity, however if you want to scale you might want to rewrite this in C++. Python is great for prototyping so I'll stick with this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;p&gt;You can grab &lt;code&gt;opencv-python&lt;/code&gt; from &lt;a href="https://pypi.org/project/opencv-python/"&gt;pypi&lt;/a&gt; - this is an unoptimised version that works on CPU - more than enough for prototyping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write Code
&lt;/h2&gt;

&lt;p&gt;First, import OpenCV and load the image you want to work with, optionally resizing it. You need to grayscale the image before applying further classification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cv2&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;

&lt;span class="n"&gt;img1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"band-small-faces.jpg"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# resize if needed
# img2 = cv.resize(img1, None, fx=0.3, fy=0.3, interpolation=cv.INTER_CUBIC)
&lt;/span&gt;&lt;span class="n"&gt;img2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img1&lt;/span&gt;  &lt;span class="c1"&gt;# not resizing in this case
&lt;/span&gt;&lt;span class="n"&gt;img3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLOR_BGR2GRAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the image provided as input:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BQYycz7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aloneguid.uk/posts/2022/03/face-detection/band-small-faces.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BQYycz7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aloneguid.uk/posts/2022/03/face-detection/band-small-faces.jpg" alt="band-small-faces" width="647" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, you need something called a Haar classifier that does the magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;haar_cascade_face&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CascadeClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./data/haarcascades/haarcascade_frontalface_default.xml"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an input it needs a model to work with. I'm passing a model that detects frontal faces. I've &lt;a href="//haarcascades.zip"&gt;attached&lt;/a&gt; available models for you to download (apparently you need to create &lt;code&gt;data/haarcascases&lt;/code&gt; folder where your python script is).&lt;/p&gt;

&lt;p&gt;If you get an error similar to&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cv2.error: OpenCV(4.5.5) ...opencv-python\opencv-python\opencv\modules\objdetect\src\cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'cv::CascadeClassifier::detectMultiScale'&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;it usually means that path to the xml is invalid (thanks for useful messages!).&lt;/p&gt;

&lt;p&gt;And to display model results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;faces_rects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Display"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;waitKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CWL8IMb7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aloneguid.uk/posts/2022/03/face-detection/image-20220323155153397.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CWL8IMb7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aloneguid.uk/posts/2022/03/face-detection/image-20220323155153397.png" alt="image-20220323155153397" width="880" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, most of the faces were detected! Last person's leg looks like a face (you need to play with model parameters to rule this out). Last face wasn't detected because it's not frontal! Maybe use another model if you need to detect more.&lt;/p&gt;

&lt;p&gt;Same way you can detect other things with OpenCV, just supply another pre-trained model. For instance, face expressions, eyes, eyeglasses, bodies, plate numbers etc.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opencv</category>
    </item>
    <item>
      <title>Recruiters! We Were Always Remote!</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 17 Mar 2022 11:42:38 +0000</pubDate>
      <link>https://dev.to/aloneguid/recruiters-we-were-always-remote-356g</link>
      <guid>https://dev.to/aloneguid/recruiters-we-were-always-remote-356g</guid>
      <description>&lt;p&gt;As COVID-19 is ending/easing, recruitment companies are trying to lower salaries / day rates by justifying the position is now "mostly remote" or "remote". This is &lt;strong&gt;bullshit&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We were always working remote.&lt;/p&gt;

&lt;p&gt;Taking away most of the commute does not make it remote.&lt;/p&gt;

&lt;p&gt;Pre-covid we used to &lt;em&gt;waste a big chunk of our day&lt;/em&gt; but going to the office, getting tired before work starts, and getting into uncomfortable workplace.&lt;/p&gt;

&lt;p&gt;We put noise-cancelling headphones on to &lt;strong&gt;block the office environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We spent majority of meetings &lt;strong&gt;online&lt;/strong&gt; on Teams, Slack or whatever the corporate messaging platform is.&lt;/p&gt;

&lt;p&gt;We &lt;strong&gt;work during commute&lt;/strong&gt; whenever possible in terrible conditions - uncomfortable busy trains, buses etc. most of the time not being able to. And if we can't, we would use our phones to reply to emails and instant messaging apps to help with customer requests. How the hell is this not remote?&lt;/p&gt;

&lt;p&gt;And then coming home late mostly to get to bed and wake up to commute again.&lt;/p&gt;

&lt;p&gt;So what's the cost saving for us, developers, by working "remote"?&lt;/p&gt;

&lt;p&gt;We benefit from it mostly by saving on &lt;strong&gt;mental health&lt;/strong&gt;, and I can't think of more to be honest. There are side benefits as well for spending more time with families (whoever has one) and self-care. But who are really benefitting from this is companies we work for - now they need to pay zero costs for our gym memberships and other benefits we take to stay sane.&lt;/p&gt;

&lt;p&gt;What are the other benefits companies have?&lt;/p&gt;

&lt;p&gt;Developers stay focused and productive, as they are free to set up their own workplace in a way they want.&lt;/p&gt;

&lt;p&gt;If you as a company used to pay for commute, now this is gone too.&lt;/p&gt;

&lt;p&gt;Most of the time developers do work longer hours than usual, because they can. This crowd is not going to work to clock hours, most of us are working the job because we*&lt;em&gt;genuinely like it&lt;/em&gt;*. It's usual to see people working much longer hours now, and not being tired.&lt;/p&gt;

&lt;p&gt;Then, &lt;strong&gt;office space is expensive&lt;/strong&gt;, free coffee is expensive, and all the small things combined like office supplies, power, hardware, furniture, you name is adding up to quite a bit. And you need to &lt;strong&gt;hire people and pay them salaries to run the office&lt;/strong&gt;. Extra people are very expensive.&lt;/p&gt;

&lt;p&gt;But you also get extra productivity i.e. &lt;strong&gt;free developer hours&lt;/strong&gt; which are really really expensive.&lt;/p&gt;

&lt;p&gt;And I've just started this morning rant and given more time can find many more reasons.&lt;/p&gt;

&lt;p&gt;Therefore think again, do you still want to offer me lower salary? You better do the job yourself. Fully remote.&lt;/p&gt;

&lt;p&gt;We need to rethink this as a community, and raise prices for our services as companies are now getting more in return than usual.&lt;/p&gt;

</description>
      <category>work</category>
    </item>
    <item>
      <title>C++: lvalue/rvalue for Complete Dummies</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Mon, 06 Dec 2021 22:28:54 +0000</pubDate>
      <link>https://dev.to/aloneguid/c-lvaluervalue-for-complete-dummies-1jnb</link>
      <guid>https://dev.to/aloneguid/c-lvaluervalue-for-complete-dummies-1jnb</guid>
      <description>&lt;p&gt;I find the concepts of &lt;em&gt;lvalue&lt;/em&gt; and &lt;em&gt;rvalue&lt;/em&gt; probably the most hard to understand in C++, especially after having a break from the language even for a few months. So this is an attempt to keep my memory fresh whenever I need to come back to it. This topic is also super essential when trying to understand move semantics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Essentials
&lt;/h2&gt;

&lt;h3&gt;
  
  
  lvalue
&lt;/h3&gt;

&lt;p&gt;There are plenty of resources, such as &lt;a href="https://en.cppreference.com/w/cpp/language/value_category" rel="noopener noreferrer"&gt;value categories on cppreference&lt;/a&gt; but they are lengthy to read and long to understand. In general, &lt;code&gt;lvalue&lt;/code&gt; is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is usually on the left hand of an expression, and that's where the name comes from - "left-value".&lt;/li&gt;
&lt;li&gt;Something that points to a specific memory location. Whether it's heap or stack, and it's addressable.&lt;/li&gt;
&lt;li&gt;Variables are &lt;code&gt;lvalues&lt;/code&gt;, and usually variables appear on the left of an expression. For example in an expression &lt;code&gt;int x = 1;&lt;/code&gt; &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;lvalue&lt;/code&gt;. &lt;code&gt;x&lt;/code&gt; is also pointing to a memory location where value &lt;code&gt;1&lt;/code&gt; is.

&lt;ul&gt;
&lt;li&gt;Another example is &lt;code&gt;int* y = &amp;amp;x&lt;/code&gt;. In this case &lt;code&gt;y&lt;/code&gt; is &lt;code&gt;lvalue&lt;/code&gt; as well. &lt;code&gt;x&lt;/code&gt; is also &lt;code&gt;lvalue&lt;/code&gt;, but &lt;code&gt;&amp;amp;x&lt;/code&gt; is not!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Early definitions of &lt;code&gt;lvalue&lt;/code&gt; meant "values that are suitable fr left-hand-side or assignment" but that has changed in later versions of the language. For instance &lt;code&gt;const int a = 1;&lt;/code&gt; declares lvalue &lt;code&gt;a&lt;/code&gt; but obviously it cannot be assigned to, so definition had to be adjusted. Later you'll see it will cause other confusions!&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Some people say "lvalue" comes from "locator value" i.e. an object that occupies some identifiable location in memory (i.e. has an address).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  rvalue
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rvalue&lt;/code&gt; is something that doesn't point anywhere. The name comes from "right-value" because usually it appears on the right side of an expression.&lt;/li&gt;
&lt;li&gt;It is generally short-lived. Sometimes referred to also as "disposable objects", no one needs to care about them.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rvalue&lt;/code&gt; is like a "thing" which is contained in &lt;code&gt;lvalue&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sometimes &lt;code&gt;rvalue&lt;/code&gt; is defined by exclusion rule - everything that is not &lt;code&gt;lvalue&lt;/code&gt; is &lt;code&gt;rvalue&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lvalue&lt;/code&gt; can always be implicitly converted to &lt;code&gt;lvalue&lt;/code&gt; but never the other way around.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rvalue&lt;/code&gt; can be moved around cheaply&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Coming back to express &lt;code&gt;int x = 1;&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; is &lt;code&gt;lvalue&lt;/code&gt; (as we know it). It's long-lived and not short-lived, and it points to a memory location where &lt;code&gt;1&lt;/code&gt; is. The value of &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; is &lt;code&gt;rvalue&lt;/code&gt;, it doesn't point anywhere, and it's contained within &lt;code&gt;lvalue&lt;/code&gt; &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a silly code that doesn't compile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// error: expression must be a modifyable lvalue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which starts making a bit more sense - compiler tells us that &lt;code&gt;1&lt;/code&gt; is not a "modifyable lvalue" - yes, it's "rvalue". In C++, the left operand of an assignment must be an "lvalue". And now I understand what that means.&lt;/p&gt;

&lt;p&gt;A definition like "a + operator takes two rvalues and returns an rvalue" should also start making sense.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A useful heuristic to determine whether an expression is an &lt;strong&gt;lvalue&lt;/strong&gt; is to ask if you can take its address. If you can, it typically is. If you can't, it's usually an &lt;strong&gt;rvalue&lt;/strong&gt;."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Effective Modern C++&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;Are references &lt;code&gt;lvalues&lt;/code&gt; or &lt;code&gt;rvalues&lt;/code&gt;? General rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;lvalue references can only be bound to lvalues but not rvalues&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;assumes that all references are lvalues.&lt;/p&gt;

&lt;p&gt;In general, there are three kinds of references (they are all called collectively just &lt;em&gt;references&lt;/em&gt; regardless of subtype):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;lvalue references&lt;/strong&gt; - objects that we want to change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;const references&lt;/strong&gt; - objects we do not want to change (const references).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rvalue references&lt;/strong&gt; - objects we do not want to preserve after we have used them, like temporary objects. This kind of reference is the least obvious to grasp from just reading the title.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first two are called &lt;em&gt;lvalue references&lt;/em&gt; and the last one is &lt;em&gt;rvalue references&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As I said, lvalue references are really obvious and everyone has used  them - &lt;code&gt;X&amp;amp;&lt;/code&gt; means &lt;em&gt;reference to X&lt;/em&gt;. It's like a pointer that cannot be screwed up and no need to use a special dereferencing syntax. Not much to add. &lt;/p&gt;

&lt;p&gt;One odd thing is taking address of a reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ii&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// reference to i&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// pointer to i&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;iip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// pointer to i, equivent to previous line&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically we cannot take an address of a reference, and by attempting to do so results in taking an address of an object the reference is pointing to.&lt;/p&gt;

&lt;p&gt;Another weird thing about references here. To initialise a reference to type &lt;code&gt;T&lt;/code&gt; (&lt;code&gt;T&amp;amp;&lt;/code&gt;) we need an lvalue of type &lt;code&gt;T&lt;/code&gt;, but to initialise a &lt;code&gt;const T&amp;amp;&lt;/code&gt; there is no need for lvalue, or even type &lt;code&gt;T&lt;/code&gt;! For const references the following process takes place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implicit type conversion to &lt;code&gt;T&lt;/code&gt; if necessary.&lt;/li&gt;
&lt;li&gt;Resulting value is placed in a temporary variable of type &lt;code&gt;T&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Temporary variable is used as a value for an initialiser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// does not work, lvalue required&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// absolutely fine&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;  &lt;span class="c1"&gt;// same as line above, OK, but syntax preferred in modern C++&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's the time for a more interesting use case - &lt;em&gt;rvalue references&lt;/em&gt;. Starting to guess what it means and run through definition above - &lt;em&gt;rvalue&lt;/em&gt; usually means temporary, expression, right side etc. Rvalue references are designed to refer to a &lt;strong&gt;temporary object&lt;/strong&gt; that user &lt;strong&gt;can and most probably will modify&lt;/strong&gt; and that object will &lt;strong&gt;never be used again&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A classic example of rvalue reference is a function return value where value returned is function's local variable which will never be used again after returning as a function result. It's completely opposite to lvalue reference:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;rvalue reference can bind to rvalue, but never to lvalue&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rvalue reference is using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; (double ampersand) syntax, some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;get_some_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Temporary"&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_some_string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// fine, binds rvalue (function local variable) to rvalue reference&lt;/span&gt;
&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;              &lt;span class="c1"&gt;// fails - trying to bind lvalue (ls) to rvalue reference&lt;/span&gt;
&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"Temporary"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;      &lt;span class="c1"&gt;// fails - trying to bind temporary to rvalue reference&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could also thing of rvalue references as &lt;em&gt;destructive read&lt;/em&gt; - reference that is read from is dead. This is great for optimisations that would otherwise require a copy constructor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Deeper
&lt;/h2&gt;

&lt;p&gt;Newest versions of C++ are becoming much more advanced, and therefore matters are more complicated. Generally you won't need to know more than lvalue/rvalue, but if you want to go deeper here you are.&lt;/p&gt;

&lt;p&gt;So, there are two properties that matter for an object when it comes to addressing, copying, and moving:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Has Identity (&lt;strong&gt;I&lt;/strong&gt;). The program has the name of, pointer to, or reference to the object so that it is possible to determine if two objects are the same, whether the value of the object has changed, etc.&lt;/li&gt;
&lt;li&gt;Moveable (&lt;strong&gt;M&lt;/strong&gt;). The object may be moved from (i.e., we are allowed to move its value to another location and leave the object in a valid but unspecified state, rather than copying).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cool thing is, three out of four of the combinations of these properties are needed to precisely describe the C++ language rules! Fourth combination - without identity and no ability to move - is useless. Now we can put it in a nice diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aloneguid.uk%2Fposts%2F2021%2F12%2Flvalue-vs-rvalue%2Fimage-20211206212335535.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aloneguid.uk%2Fposts%2F2021%2F12%2Flvalue-vs-rvalue%2Fimage-20211206212335535.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, a &lt;em&gt;classical lvalue&lt;/em&gt; is something that has an identity and cannot be moved and &lt;em&gt;classical rvalue&lt;/em&gt; is anything that we allowed to move from. Others are advanced edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;prvalue&lt;/strong&gt; is a &lt;em&gt;pure rvalue&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;grvalue&lt;/strong&gt; is &lt;em&gt;generalised rvalue&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;xvalue&lt;/strong&gt; is &lt;em&gt;extraordinary or expert value&lt;/em&gt; - it's quite imaginative and rare.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually &lt;code&gt;std::move(x)&lt;/code&gt; is an &lt;code&gt;xvalue&lt;/code&gt;, like in the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It both has an identity as we can refer to it as &lt;code&gt;v1&lt;/code&gt; and we allowed it to be moved (&lt;code&gt;std::move&lt;/code&gt;). It's still really unclear in my opinion, real headcracker I might investigate later.&lt;/p&gt;

&lt;p&gt;But below statement is very important and very true:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For practical programming, thinking in terms of rvalue and lvalue is usually sufficient. Note that every expression is either an lvalue or an rvalue, but not both.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The C++ Programming Language&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reference Geek-Out
&lt;/h2&gt;

&lt;p&gt;If you take a reference to a reference to a type, do you get a reference to that type or a reference to a reference to a type? And what kind of reference, lvalue or rvalue? And what about a reference to a reference to a reference to a type?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;rr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// rvalue reference&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;lr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// lvalue reference&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;rr_rr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rr_i&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// int&amp;amp;&amp;amp;&amp;amp;&amp;amp; is an int&amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;lr_rr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rr_i&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// int&amp;amp;&amp;amp;&amp;amp; is an int&amp;amp;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;rr_lr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lr_i&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// int&amp;amp;&amp;amp;&amp;amp; is an int&amp;amp;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;lr_lr_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lr_i&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// int&amp;amp;&amp;amp; is an int&amp;amp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning the rule is simple - &lt;strong&gt;lvalue always wins!&lt;/strong&gt;. This is also known as &lt;strong&gt;reference collapse&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What is &lt;code&gt;int*&amp;amp;&lt;/code&gt;? It's a &lt;em&gt;reference to a pointer&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=msvc-170" rel="noopener noreferrer"&gt;Lvalue and Rvalues (C++) (docs.microsoft.com)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.cppreference.com/w/cpp/language/value_category" rel="noopener noreferrer"&gt;Value Categories (cppreference.com)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3055.pdf" rel="noopener noreferrer"&gt;A taxonomy of Expression Value Categories (open-std.org)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/3601661/80858" rel="noopener noreferrer"&gt;What are rvalues, lvalues, xvalues, glvalues, and prvalues? (stackoverflow.com)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
    </item>
    <item>
      <title>C++ 17: IF and SWITCH With Initialisation</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Thu, 02 Dec 2021 16:35:02 +0000</pubDate>
      <link>https://dev.to/aloneguid/c-17-if-and-switch-with-initialisation-4p0f</link>
      <guid>https://dev.to/aloneguid/c-17-if-and-switch-with-initialisation-4p0f</guid>
      <description>&lt;p&gt;In C++ 17, &lt;code&gt;if&lt;/code&gt; statement can have an initialisation clause i.e. instead of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? I could just write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it's almost the same. Initialisation clause &lt;em&gt;is valid until the ned of the &lt;code&gt;if&lt;/code&gt; part&lt;/em&gt;. To demonstrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OK&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"if 1"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// OK&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"else:"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// left the scope, so the following line won't compile:&lt;/span&gt;
&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also means RAII applies to the initialisation phase i.e. if init instantiates a class on stack, a destructor will be called.&lt;/p&gt;

&lt;p&gt;This is useful in many scenarios, for instance guard initialisation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;lock_guard&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mtx&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// safely use the collection&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can achieve the same in pre C++17 codebase with the following code, which is equivalent to above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;lock_guard&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mtx&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// safely use the collection&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it's just syntaxically longer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt; - the object in initialisation clause &lt;strong&gt;must have a name&lt;/strong&gt;, and if it doesn't, it's automatically created and destroyed before the first statement inside &lt;code&gt;if&lt;/code&gt; executes. Basically, it's destroyed as soon as possible, so no resources are wasted. It would make sense, as you are not referencing it.&lt;/p&gt;

&lt;p&gt;Same goes for &lt;code&gt;switch&lt;/code&gt; statement, absolutely no differences from &lt;code&gt;if&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cpp</category>
      <category>cpp17</category>
    </item>
    <item>
      <title>C++ Structured Binding - From Zero to Hero</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Wed, 01 Dec 2021 14:00:37 +0000</pubDate>
      <link>https://dev.to/aloneguid/c-structured-binding-from-zero-to-hero-n5i</link>
      <guid>https://dev.to/aloneguid/c-structured-binding-from-zero-to-hero-n5i</guid>
      <description>&lt;p&gt;Structured binding allows to initialise multiple entities by members of another object, for instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;stb_node&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;stb_node&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"First"&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Produces output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1, First
1, First
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you break in a debugger, it shows that there are two local variables &lt;code&gt;int u&lt;/code&gt; and &lt;code&gt;string v&lt;/code&gt; created. &lt;code&gt;u&lt;/code&gt; and &lt;code&gt;v&lt;/code&gt; are called &lt;strong&gt;structural bindings&lt;/strong&gt;. The purpose of structural bindings is &lt;em&gt;to make code more readable by binding the value directly to names&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;This becomes more apparent when working with maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...;&lt;/span&gt;

&lt;span class="c1"&gt;// pre - C++17 way&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// C++17 way&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the second syntax option, the code is carrying the context that it's working with &lt;code&gt;index&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt;, unlike &lt;code&gt;el.first&lt;/code&gt; and &lt;code&gt;el.second&lt;/code&gt; which doesn't make sense. Of course you can create references to key and value i.e. &lt;code&gt;auto&amp;amp; index = el.first&lt;/code&gt; (and that's what I often do to improve readability) but that makes code more verbose.&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt;decltype(index)&lt;/code&gt; is &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;decltype(value)&lt;/code&gt; is &lt;code&gt;string&lt;/code&gt; - there is no special magic types involved, these are just other names for struct members.&lt;/p&gt;

&lt;p&gt;Also, as with normal assignment, &lt;code&gt;auto [u, v] = node1&lt;/code&gt; creates a &lt;strong&gt;copy&lt;/strong&gt; of struct members, with all the consequences i.e. modifying &lt;code&gt;u&lt;/code&gt; modifies a copy of &lt;code&gt;u&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qualifiers
&lt;/h2&gt;

&lt;p&gt;To avoid copying and enforce constant expressions, you can use qualifiers, for instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;u1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;fails on line 2 when trying to modify a copy of &lt;code&gt;node1.index&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;u2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;u2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;fails on line 2 when trying to modify a &lt;strong&gt;reference&lt;/strong&gt; of &lt;code&gt;node1.index&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Usages
&lt;/h2&gt;

&lt;p&gt;In general, structured bindings can be used with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Structs with public data members as above.&lt;/li&gt;
&lt;li&gt;Raw C-style arrays.&lt;/li&gt;
&lt;li&gt;"Tuple-like" objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For structs or classes, the decomposed members must be members of the same class definition. Inheritance is not supported. So this won't work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;   &lt;span class="c1"&gt;// won't work, gives an error "type "C" has no components to bind to"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For arrays, binding only works for arrays of known size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// OK&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// won't compile, gives an error "there are more elements than there are binding names"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;std::tuple&lt;/code&gt; decomposes nicely i.e.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;std::pair&lt;/code&gt; is just like before, and is logically a subset of tuple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redefining Values
&lt;/h2&gt;

&lt;p&gt;Looking at the example before, how do you call &lt;code&gt;do_someting&lt;/code&gt; again and assign to &lt;code&gt;a, b, c&lt;/code&gt;? You can't. However, if the types match, use  &lt;code&gt;std::tie&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// redefine:&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course you could just introduce new set of variables, however you wouldn't be able to do that in a loop, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;boyer_moore_searcher&lt;/span&gt; &lt;span class="n"&gt;bm&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()};&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;beg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="n"&gt;beg&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cpp</category>
      <category>cpp17</category>
    </item>
    <item>
      <title>Thoughts on Rust at First, but then Ramblings on Top Programming Languages</title>
      <dc:creator>Ivan G</dc:creator>
      <pubDate>Wed, 29 Sep 2021 15:03:39 +0000</pubDate>
      <link>https://dev.to/aloneguid/thoughts-on-rust-at-first-but-then-ramblings-on-top-programming-languages-26g6</link>
      <guid>https://dev.to/aloneguid/thoughts-on-rust-at-first-but-then-ramblings-on-top-programming-languages-26g6</guid>
      <description>&lt;p&gt;Below post has started from me thinking about Rust on a weekend, and then expanded a bit. I was merely trying to understand whether C/C++ will die eventually and be replaced with something like Rust.&lt;/p&gt;

&lt;p&gt;First of all, Rust is great, good performance, interesting language, more accessible than C.&lt;/p&gt;

&lt;p&gt;However, thinking more about it - forces developer to start from clean slate.&lt;/p&gt;

&lt;p&gt;There is no interop with C++. There is with C, meaning that you can wrap C++ in C calls, make a dynamic library and only then call it from Rust. Wrapping is not always a good idea, as C is unsafe and C++ is safe, plus you will have to translate some rich C++ data structures into C, meaning performance overhead. Also this prevents overall program compiler optimisation, meaning again performance loss. Also you will have to wrap C interface from Rust, again another performance loss.&lt;/p&gt;

&lt;p&gt;System programming close to metal and OS is primarily done in C, so Rust is a very weird citizen there. Like Linux and Windows is all C, and according to various sources there is no vision to use Rust.&lt;/p&gt;

&lt;p&gt;The promised safety is really arguable. Usually you will hear arguments that Rust is safer than C++. But that’s just not true for Modern C++. It could be true when comparing Rust to the state of C++ maybe 20 years ago.&lt;/p&gt;

&lt;p&gt;New successful languages like TypeScript, Scala, Kotlin all have one thing is n common - they are built on heritage and are completely comfortable in their area. I mean for example TypeScript is actually JavaScript on steroids. You can take js file, change extension, and that will be a valid TypeScript program. It’s not ideal, but it will work. Apparently you can also use any JavaScript library from TypeScript and vice versa. You can mix and match in one program. This is big.&lt;/p&gt;

&lt;p&gt;Scala is another example, as it builds on JVM, can use any native Java library, and can be compiled to use from classic Java as well! Same with Kotlin. And the wast amount of platforms JVM runs on.&lt;/p&gt;

&lt;p&gt;Python is… well, still good. Most of Python libraries are actually written in C++ with python wrapping on top. Python is old and well developed. It even runs on JVM.&lt;/p&gt;

&lt;p&gt;Golang is just golang, it does not claim to be a replacement for anything, bit fits well into the area of writing small simple utilities for command line where others would be too heavy. Some do write more complicated code, for instance Docker is done in Go, however it is not common. You would not write anything performance critical in Go either, mostly due to unpredictable garbage collection issues. And it’s not powerful enough to scale to really complex code. Remember that Docker is essentially an orchestrator gluing together different parts of OS to make it more accessible to mortals. It does not actually run when container runs.&lt;/p&gt;

&lt;p&gt;C# is a weird beast. It builds on top of Java principles, but doesn’t run on JVM. It’s really way ahead of Java in terms of features and productivity, but used to only compile for Windows. Today cross platform support is great, but it may be too late for the party. It may end up like Windows Phone, it’s hard to tell. I hope not. Btw Windows Phone was way more superior than iOS and Android, but that didn’t matter at the end. It was just really late to the party.&lt;/p&gt;

&lt;p&gt;Where does Rust leave us? I’m really confused, but it seems nowhere. Yes ecosystem is growing and there is just a lot of good stuff. But always almost enough, not completely enough. Sure if you are building software that is a utility or web server it’s ok to use, but not something really deep, no way to reuse rock solid code that worked for decades already. You’ll have to create some weird workarounds or write stuff that existed for decades from scratch. Scratch that.&lt;/p&gt;

&lt;p&gt;Rust is not supported on as many platforms as C/C++ is. Meaning embedded and IoT is not fully accessible.&lt;/p&gt;

&lt;p&gt;Tooling is just not there. There’s no cool IDEs like Visual Studio (which btw works perfect for Linux programming) or CLion or Eclipse. We have some half baked support in IDEA, Vs code and some others. But no really cool tooling C++ has grown to.&lt;/p&gt;

&lt;p&gt;Do I hate Rust? Oh no, not at all. I think it’s a beautiful language. Very clear, with no legacy like C++.&lt;/p&gt;

&lt;p&gt;Is it superior to C++? No, I don’t think so. Everything Rust does C++ does, if you use more or less recent C++ version. Even 10 year old C++ will do. But, the problem with C++ is novice programmers - the language is just so rich, it’s much easier to escape out of the sage box and do something stupid. But that’s just language evolution, eventually Rust will be there too as history shows.&lt;/p&gt;

&lt;p&gt;Would I choose Rust for my next project? It depends. If I need to interface with OS or use third party C/C++ libraries than no. I would probably use it for command line utils or self sufficient cross platform network utilities. But then why won’t I just stick with C++ if I already use it? So far only as a learning exercise.&lt;/p&gt;

&lt;p&gt;Well, I think I’ll stick with C++, but I’m open for criticism.&lt;/p&gt;

&lt;p&gt;P.S. Originally published &lt;a href="https://www.aloneguid.uk/posts/2021/09/rust-or-no-rust/"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
  </channel>
</rss>
