Just some general advice for any programmers that see this comment: When anybody tells you "NEVER do this in programming", they're in most cases over-simplifying and generalizing, OR they don't know enough about the topic in the first place. For example, a while ago I watched a video saying that you should never use "else" statements and instead work with other options like guard clauses and whatnot. While that is true in many cases and that video helped me make my code a lot more readable, there are just a few cases where strictly not using "else" just makes it unnecessarily complicated for everyone, both you and readers of your code. EVERYTHING in programming has its use, no matter what anybody else tells you. Sometimes those use cases are rather niche, sometimes they aren't. Even stuff like "goto", which is almost always a terrible idea, has some very rare cases where it might just make the code easier to understand than whatever the alternative is. This video also only goes over a single way that switch statements are often used: to return a pre-determined value based on another value, and I agree that switch statements might not be the best option for this. Though, a few programming languages like C# and Java have "switch EXPRESSIONS" for this specific purpose which are in fact very readable since they look similar to a typical map syntax. However, switch statements have LOTS of other purposes that can sometimes be a pain to do differently. So saying that "switch statements are generally bad" and "you should never use them" is just completely wrong. It should be saying "don't use switch statements like this" or something. Some additional comments to the video: 1. The switch-case shown in the beginning is written in an unnecessarily complicated way... You could just put a return into each of the cases. That would almost cut the length of that function in half already, since you wouldn't need the variable, the assignments would be replaced by the returns, the breaks would not be necessary anymore, and the return at the end would also not be needed. 2. If you have a map that will be reused over and over again, it should be declared outside of the function and made readonly if you want to make sure (since I think this is JavaScript, Objects.freeze(map) will do the trick here).
Nope. Switch cases are better than OOP as they jump directly to the place in memory without wasting cpu cycles. They also don't force you into convoluted design patterns making your code not only less performant but harder to reason about with. Your technique with the map wastes cpu cycles. If you know how maps work under the hood, you'd know why it's a bad idea.
Exactly. The map requires dynamically allocating memory and hashing the input on every check. The switch never leaves the stack and is a simple jump table.
Another useful feature of switch case is fall through, its when you want multiple input values to hit the same case/block, switch makes it really clean.
When I saw the video I thought: “what am I missing? This seems cool, but in reality it’s actually worse from cpu cycles and memory management perspective”. I’m glad I wasn’t the only one who thought about that.
First thing that came to my mind too. Switch case is the most efficient way to do this. Maps require hash and equals to find the right place in memory. That wastes CPU cycles. But this will only become a problem when the code is used heavily. If it's not often called, one could use this for code clarity. Still I would advise to use the switch case instead because everyone knows what the program is about to do when they see a switch-statement and you never know if the code will be hit harder in the future. Perhaps make the switch-statement more readable by making oneliner cases (if your company coding policy allows it) or use modern language features.
I think the enhanced enum is a better choice. It is type safe and guarantees you cover all options. You could also return objects so if you wanted to store more than just caffeine, like vitamins, or flavor, you could just add that to the object without refactoring everything.
Agreed with all you said, even without the new enhanced enum features, just plain old Dart enum would be better, like you said, type safe, ensures you covers all the options, refactoring becomes a breeze. Then go further with enhanced enums and objects. This is actually not so good advice/example, sure maps have their usage too, not saying that 😀💙
@@hyungtaecf That is the point. You could then reuse it anywhere you want and not just in that one piece of code. If you wanted to reuse the map in other parts of the codebase instead of this one function you’d need to define it separately anyways.
@@farhanaditya2647 In the backend it definetely iterates, whatever code that manages maps in javascript needs to iterate through the map to get a value
@@farhanaditya2647 I'm fairly certain it iterates in the backend, it's just invisible to the user. I'd also wager it's significantly slower then using a switch statement, which "could" matter depending on how it's used.
@@mitaka_78 Switch optimally has runtime complexity of O(1), at worst O(n) but only for really really large n. If the map you're using is a HashMap, like in Java, its runtime complexity for lookup is O(1), i.e. the same as a switch. If the map you're using is a binary tree, like in cpp, the runtime complexity for lookup is O(n), because here acutal iteration takes place. If it's a binary search tree, it's O(log n). In the end it really depends what programming language you're using and what underlying structure is used for the map. Switches are safe bet, because their implementation doesn't vary between programming languages as to affect the performance, and it's the most memory efficient option. In addition, it allows easy implementation of "fall-through" behavior. In Java however, a HashMap will usually be as performant as a switch, and might even be faster depending on how you use it. This again depends on what your JIT does with your Map or Switch. There really are no easy answers here. The safest bet is try both, check their performance and then go with the faster option.
Please, don’t. This is very inefficient. From the stackoverflow “Switches will always be as fast as if not faster than hash maps. Switch statements are transformed into direct lookup tables. In the case of Integer values (ints, enums, shorts, longs) it is a direct lookup/jmp to the statement. There is no additional hashing that needs to happen. In the case of a String, it precomputes the string hash for the case statements and uses the input String's hashcode to determine where to jump. In the case of collision, it does an if/else chain. Now you might think "This is the same as HashMap, right?" But that isn't true. The hash code for the lookup is computed at compile time and it isn't reduced based on the number of elements (lower chance of collision).“
Implementation will vary from language to language, but this is generally correct. Also if you ever find yourself using switch case on a string there's a decent chance it should actually be an enum.
@@luxraider5384 Don't worry about it, next year we will have a new iThing with a 100% faster CPU so you won't notice the lag when scrolling down a list of text boxes :)
For this example, yes a switch statement seems overkill. But when you need to do some computational logic before returning something, or maybe you don't want to return at all, absolutely use a switch statement. In some situations, it makes sense to. It's simply false to say "SWITCH STATEMENT ARE BAD" because some situations require it.
If you do this in c-type languages, you trade O(1) for O(n) or O(log n) (av. lookup runtime complexity of binary tree, and binary search tree respectively). A hashmap would be the only option I know that can compete with switches in terms of look-up speed. Safest option is always: try all options and use the best one. And by try I mean: also try server-side and client-side performance, if you use a programming language that uses JIT.
Two points: 1: While not the greatest for readability or code quality, C style switch statements are FAST, and in a performance intensive environment, that could make a measurable difference depending on the amount used throughout the code. 2: If you want to do any type of conditional logic based on the compared value, you may as well just use a switch in any case, as you will need to do the check on the returned value anyways.
IMO, there's nothing wrong with the switch case method, since it's much more flexible. The map approach is indeed cleaner if we just want to return a value response, but it's not going to work for anything that's more complicated like we have to do some evaluation/calculation/etc. In any case, it's a good advice nonetheless. Just my $0.02
Using object literals instead of switch case blocks using logic instead of simple logic for languages like JS is quite simple too, as you can encapsulate each block logic in a function and assign it as object literal values, then, simply invoke the matching key function.
I'll be thrown out of window (y'know the meme). switch (number) { case 1: return "one"; case 2: return "two"; } return "many"; Same number of lines. Works with almost all C-like languages. No extra memory required for container.
😂😂 funny meme 😂 Obviously this video is a little bit over exaggerated. It's cool to know some funky ways to replace the typical Switch statements tho 👏
switch allow you to choose not to break a case, which map doesn’t. Such as this sample: const num = 3 switch (num) { case 3: console.log(`${num} is larger than 2`); case 2: console.log(`${num} is larger than 1`); case 1: console.log(`${num} is larger than 0`); break; } When this is run, it will print out all 3 lines of string to the console, since we didn’t break the upper ones. This could be useful in some situation.
This is a great tip but I'd recommend creating a constant map outside the function if it is independent of function inputs also enhanced enums can be used but for simple use cases it makes the code less readable and unnecessaryly complex
I prefer declaring vars only within the scopes they're used, even if they're const. And if the only scope available is global, I use block-scoping to limit the lifetime of the var. This makes it easier for garbage collectors to reduce memory use, and adds context to names (reducing the need for long names), it also reduces the cognitive load because there's less vars to work with, and reduces scope/namespace pollution. Of course, the downside is deeper indentation. I wish there was a lang where var scoping didn't require indentation to make it readable. Rust has the `drop` fn, but it only works on heap-allocated stuff, not stack frames
@@Rudxain sounds instead like you'd possibly increase the amount of GC runs and reducing performance instead. Which is ok I guess depending on what kind of program you are doing
@@Erlisch1337 True. Sometimes it's ok to declare constants outside of a function, if the constant is heap-allocated and contains more than 256 bytes of data. This is specially useful if the constant is required by more than 1 fn, and guarantees that only 1 allocation is performed (instead of relying on the optimizer)
This makes sense unless you’re writing C code where you’d have to build your own map struct and put it in an array and it wouldn’t be nearly as visually appealing
On a resource limited embedded platform the switch/case form would be preferable due to the much smaller code and data generated by the compiler, compared to a std::map with its internal binary tree implementation. A switch/case will often be implemented by the compiler as a simple jump table.
Strong disagree with switch statements being bad. Imagine you use an object literal mapping, and then realize down the road you need logic to be executed within one or more of the switch cases. What then? Switch/case is designed exactly for the scenario you gave here and is almost objectively "easier" to read because it's literally telling you "When the case is that a variable is X, execute the below code." Which is more syntactically readable than chaining if statements.
The code is more compact but takes longer to execute because the CPU has to run through an algorithm to find the text string within the dictionary. What's more important, CPU time, or your time scrolling down a few extra lines of code? The moral of the story is: *ALWAYS* think about the run time performance of the code you write, and decide if it matters to your application or not.
"The CIA wants you to think that the switch statement is the same thing as if-else-if chain. It's not. Switch is the most powerful construct in the C language" - Terry Daves, reworded
Plus it’s scalable and faster with larger datasets. Switch statements do have their uses, and maps have their separate uses. Know when to use each of them
This is only works for functional value returns like shown. Switch case still useful if the switch case is about different ways of execution or algorithm. Also not all programming language have complete feature set of Map like shown, either lacks or not supported at all. But still though. Amazing awesome yey thancc
switch statement is not bad. code readability always rely on your current architecture and structure. in your sample it looks clean because the process is simple, but when we talk about different problems like an OOP model that follows DDD event mutations then definitely hash map will not work at all times, we need the switch statement to make the code more readable. eg. abstract IDEvent class ShipmentCreated extends IDEvent class ShipmentDeparted extends .. class ShipmentArrived extends .. ... etc events class Shipment // private fields ... void apply(IDevent e) { switch(e) { case ShipmentCreated: // mutate private fields break; case ShipmentDeparted: // mutate private fields break; case ShipmentArrived: // mutate private fields break; default: throw NotSupported(e); } }
I benchmarked switch vs. std::map in C++. The map is over two orders of magnitude slower. Although that may not matter if your calls are not in a critical loop.
Switch case with strings almost always compiles to a big ‘if else’ block. Switches with strictly numeric values will optimize to an array or to raw jmp statements, which is a lot faster than if else or map.
TL;DR Use switch case if you have no default value and your type is enum. TS;WM Switch might actually be useful, if you're not using a "default value", because map doesn't track null appearance. Switch case lets you know when you're not covering all of the possible outcomes. Not particularly useful for your example, since your type is a string that can be just about anything, but in case of enums it is ideal.
i mean... in that specific case, it makes sense, but it depends on a situation like when you want to execute more complex instructions, you can obv always have some array of functions and execute the right function or whatever, but it doesn't always make sense to do it
Nothing stopping you putting the case, statement, and break all on the one line for compactness; with tabbing to align them vertically for readability...
Ah yes, dynamically allocating memory for a map is totally worse than a jump table. What you are looking for is something like a switch expression, but I have no idea if Flutter has that.
It’s attractive to the eye but older devs that see memory leaks as a possible issue this technique isn’t gonna look great, in js the object looks very simple but this wouldn’t be so popular in a hashmap. I’ve seen this endlessly in js projects and when it scales up we end up with constant.js files with dozens of js objects, not sure it’s the most optimal thing either.
This is really depend on language your using , There's nothing wrong in using switch statements and sometimes you don't even have a choice just to use them, in c++ using switch statements is consider to be good than using if else when dealing in big enumerated value. I rather choose switch statements rathen than using map, or any other storage type.
But initialize a map object for each getCafeine execution is not good. Switch is build on compilation time and your map on execution time. I agree to write a cleaner code, but not beyond the point to sacrifice performance.
what if the value from a switch statement may come varying functions that require varying parameters, such as deserializing something including its context
What do we write if two different types should return the same caffeine value? Do we need one line for each type or can we say something like (type1 || type2) : '10mg'
Just use an enum instead! It's basically an integer, so it's N times more efficient than a string comparison and the difference will show when you have thousands of entries
This is really helpful! Some languages don't have support for enhanced enums, unlike Dart. This technique can be used there! Thanks for the video Louis!
map requires knowledge of map and its layout, switch is vastly more understandable by more people and is perfectly readable, even if it takes up more lines, and is faster.
i find this solution less readable xD like the normal if more and there is no need to declare a var caffeine if it only gets returned so i would do: if(type==='Coffee')return '95 mg' if(type==='Redbull')return '147 mg' ... return 'not found' so you always see that type is the thing you are looking for, if the list is long.
Another benefit you’re not taking into account is that switch statements in combination with an enum are exhaustive (as long as you don’t use a default case).
Either you don't know what you are talking about or I don't. How can using a map replace the functionality of a switch? A switch case is NOT a data structure. You are treating it as though its purpose is to store data. It is a conditional statement (like if statements) where you can run whatever code you like if a certain case-condition is met.
This is not necessarily good advice. Using a map internally hashes the keys. Which is more work. Instead switch case guarantees direct access in most languages. Depends on the use case, but for most part switch case should work.
This will be featured in language conferences. This means it will blow up someday. Please do not flag this as misinformation even though it is. BTW FYI dart documentation is not supposed to be your 1st langauge. If unvoidable, learn some other close-to-metal languages and data structures, so you won't end up making something like this.
Why ppls always shows the most bulkiest way when showing a switch? If you just simply return from the switch directly, the first code snippet would look pretty good already whitout sacrificing the flexibility of using switch.
I feel like that code is cleaner for simple things like returning a string, though if you want more complex functionalities Switch statements still seem to be the way to go, their structure seems much better for more complex functions.
Dont like this type of "Never do this again" in this particular case you are right but someone could interpret it as "switch case is bad" when it is just a tool. Programmers often have the problem of "when you have a hammer every problem starts looking like a nail". No tool is good or bad but they have different use cases so just learn that they exist and how they work so when you find a problem you can choose which tool is better suited for the job.
This is bad code masquerading as good code... careful, these are not equivalent and in just a tiny more complex examples (run functions in the values) would have got jump back to switches since these are not evaluated until called. And the String "caffeine" isn't needed and it's only there to make the hash map example viable.
this completely fails once you want to do anything other than simply return a simple lookup value (which anything similar in effect to an associative array will work fine). there's nothing wrong with switch statements, but there is something wrong with telling people a certain coding structure is bad for some arbitrary reason
The switch statement was not invented for this use case, that's why it looks bad if compared to a map or an enum. It mainly used when the logic performed by the program is different depending on the value of the variable the switch is applied to.
Interesting. In my new project, I was thinking about using switch statements instead of super nested if else statements, but maybe this is a much better solution. 🤔🤔🤔🤔
Keep in mind that this solution has a drawback compared to switch-case statements, especially when used inside a widget tree. Instantiating a map with a considerable amount of data or widgets inside it, will increase the usage of memory and decrease performance.
Also: The example shown in the video could be more readable without removing the switch-case statement. Just return the value directly instead of using the String caffeine and you're down to just 12 lines of Code instead of 20.
This video completely ignores the fact that switch statements can be used for executing blocks of code and not just mapping values. Yes, the map is better for this case but is definitely not the solution to all switch statement usages.
Both are bad. Make a Drink type, give it a "Caffeine" property, and call it that way. Alternatively, make an interface and make a class per drink(in case you require complex computations specific to the drink). Then, you can easily expand it with the use of a database, which will make it easy to compute even thousands of cases.
That's not exactly the case if the language doesn't support automatic fallthrough, in C/C++ the two cases would pretty much compile to the exact same thing but that supports automatic fallthrough, in C# the switch would likely be very slightly more performant and it doesn't perform automatic fallthrough however the break is still required (which is stupid honestly, why eliminate it but keep the requirement for the break?) making it better to use the lookup table in C# in such a simple case. In other languages it depends but if they perform automatic fallthrough or requires breaks anyway it is easier to read the lookup table.
Why do you declare the String before the map (totally unnecessary), and why isn't the map a static variable? You have no idea what your compiler is going to do, but it might create than map with every call to the function. I did some tests in a few languages, and sure enough, without static declaration, your map is created with every iteration of the function. You did what's in msg1. I did what's in msg2. from random import choice from timeit import timeit letters = 'abcdefg' candidates = letters + 'hijk' lookup1 = dict(map(lambda x: (x[1], x[0]), enumerate(letters))) def msg1(name: str): lookup = { 'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6 } return lookup.get(name, -1) def msg2(name: str): return lookup1.get(name, -1) if __name__ == '__main__': print(timeit(lambda: msg1(choice(candidates)), number=1_000_000)) print(timeit(lambda: msg2(choice(candidates)), number=1_000_000)) Output: 0.3260329579934478 0.2109164169523865 Your technique is 50% slower than the static map. Just do this: _caffeine_map = { .... } def getCaffeine(name: str) -> str: return _caffeine_map.get(name, 'Not found') No risk of reinitializing _caffeine_map if your compiler / interpreter is crap, no redundant variables (which most IDEs - at least JetBrains ones - would warn you about), and more concise code. This could easily be done in most programming languages. I'm not a JavaScript user, so maybe the const equates to static, but I'm not convinced.
I mean, sure. Using an object is great. But making the blanket statement that switch-case is bad, is pretty bad. Embedded C programming really benefits from the compiler optimization of using switch-case for smaller footprints.
I dont think that its "better to read" that just a matter of taste. The Switch statement therefore has the advantage that you can put addtional / extra lines of code to individual cases because you can place as many lines of code as you want between case XY: and break; but if you get the case that you have to implement an addtional-extra behaviour to a specific case you are rewritig the function to the switch-statement to fix this. :) // In the very-base cases its not hardcoded at all but dynamically set-up by a database and modifyable by options dialogue.
If you are gonna make a list of choices you are better off making a actual code that is a list, not a list of codes. Make a tuple or array and put your options in there as a condition to trigger while using if else statements elsewhere for the action.
If you need to do some calculations depending on the value, you'd be back where you started with a switch statement. There's nothing bad about switch statements in the example you provided!!!
This is fine for readability and HORRIBLE for performance. I don't know what language you're using, but any compiled language will optimize a switch statement into a jump table, which is way faster than allocating a map on the heap, initializing it, and then binary searching through it to find your value. Your technique also kinda falls apart if you're doing any actual work in the switch statement, because then you have to pull that out into discrete functions (or lambdas) and put references to that in the map, which is probably good practice but also probably doesn't make things much if any easier to read.
I guess the performance hit goes away if the map is only initialized once, rather than every time the function is called, but that's not what you did in this example.
Why are people saying that switch statements are ugly? They are literally better than if else. Also this example, as several people mentioned, has unnecessary breaks inside of the switch. Is this some sort of a switch slander video? Trying to defame us???
I'm not sure you needed to explain in detail how the Switch Statement works considering that your target audience should be people who are using the Switch Statement because they know how to use it.
You make a good point under certain situations such as the example provided, but it's terrible advice if taken as a general rule. The video title isn't helping anything either, giving the wrong impression that switch statements are never useful.
Just some general advice for any programmers that see this comment: When anybody tells you "NEVER do this in programming", they're in most cases over-simplifying and generalizing, OR they don't know enough about the topic in the first place.
For example, a while ago I watched a video saying that you should never use "else" statements and instead work with other options like guard clauses and whatnot. While that is true in many cases and that video helped me make my code a lot more readable, there are just a few cases where strictly not using "else" just makes it unnecessarily complicated for everyone, both you and readers of your code.
EVERYTHING in programming has its use, no matter what anybody else tells you. Sometimes those use cases are rather niche, sometimes they aren't. Even stuff like "goto", which is almost always a terrible idea, has some very rare cases where it might just make the code easier to understand than whatever the alternative is.
This video also only goes over a single way that switch statements are often used: to return a pre-determined value based on another value, and I agree that switch statements might not be the best option for this. Though, a few programming languages like C# and Java have "switch EXPRESSIONS" for this specific purpose which are in fact very readable since they look similar to a typical map syntax.
However, switch statements have LOTS of other purposes that can sometimes be a pain to do differently. So saying that "switch statements are generally bad" and "you should never use them" is just completely wrong. It should be saying "don't use switch statements like this" or something.
Some additional comments to the video:
1. The switch-case shown in the beginning is written in an unnecessarily complicated way... You could just put a return into each of the cases. That would almost cut the length of that function in half already, since you wouldn't need the variable, the assignments would be replaced by the returns, the breaks would not be necessary anymore, and the return at the end would also not be needed.
2. If you have a map that will be reused over and over again, it should be declared outside of the function and made readonly if you want to make sure (since I think this is JavaScript, Objects.freeze(map) will do the trick here).
not js, but good comment
@@CryMore13 Thank you :) Also, what is the language used in the video, if it's not JS? Because to me it looks 100% like JS code 🤔
@@KanashimiMusic dart
@@ivanbilinchuk9155 Ah alright, I've actually never heard of that. Thanks :)
@@KanashimiMusic you can see on 0:17 that is not JS because of the variable declaration "String Caffeine;"
Nope. Switch cases are better than OOP as they jump directly to the place in memory without wasting cpu cycles. They also don't force you into convoluted design patterns making your code not only less performant but harder to reason about with.
Your technique with the map wastes cpu cycles. If you know how maps work under the hood, you'd know why it's a bad idea.
Exactly. The map requires dynamically allocating memory and hashing the input on every check.
The switch never leaves the stack and is a simple jump table.
Another useful feature of switch case is fall through, its when you want multiple input values to hit the same case/block, switch makes it really clean.
When I saw the video I thought: “what am I missing? This seems cool, but in reality it’s actually worse from cpu cycles and memory management perspective”. I’m glad I wasn’t the only one who thought about that.
First thing that came to my mind too. Switch case is the most efficient way to do this. Maps require hash and equals to find the right place in memory. That wastes CPU cycles. But this will only become a problem when the code is used heavily. If it's not often called, one could use this for code clarity. Still I would advise to use the switch case instead because everyone knows what the program is about to do when they see a switch-statement and you never know if the code will be hit harder in the future. Perhaps make the switch-statement more readable by making oneliner cases (if your company coding policy allows it) or use modern language features.
In a Dart perpective yes, but this is a "general purpose" technique
As a ts dev I find it awesome
I think the enhanced enum is a better choice. It is type safe and guarantees you cover all options. You could also return objects so if you wanted to store more than just caffeine, like vitamins, or flavor, you could just add that to the object without refactoring everything.
Agreed with all you said, even without the new enhanced enum features, just plain old Dart enum would be better, like you said, type safe, ensures you covers all the options, refactoring becomes a breeze. Then go further with enhanced enums and objects. This is actually not so good advice/example, sure maps have their usage too, not saying that 😀💙
But you have to create it outside of the block of code which is not good for readability…
@@hyungtaecf That is the point. You could then reuse it anywhere you want and not just in that one piece of code. If you wanted to reuse the map in other parts of the codebase instead of this one function you’d need to define it separately anyways.
@@rydmike I’ve been enjoying flex color scheme. Strong work 💪
@@JustinHefley Thanks, that's nice to hear 😃🙏💙
Switch statements are not "bad" and in many cases they're great, but in this particular example you're right it's easier to use lookup tables
Also memory wise is more efficient, one is just doing some checks, another is instantiating an object, iterating through it to find an item
@@mitaka_78 There is no iteration going on here. You just plug in a key and see if the key is associated with a value.
@@farhanaditya2647 In the backend it definetely iterates, whatever code that manages maps in javascript needs to iterate through the map to get a value
@@farhanaditya2647 I'm fairly certain it iterates in the backend, it's just invisible to the user. I'd also wager it's significantly slower then using a switch statement, which "could" matter depending on how it's used.
@@mitaka_78 Switch optimally has runtime complexity of O(1), at worst O(n) but only for really really large n. If the map you're using is a HashMap, like in Java, its runtime complexity for lookup is O(1), i.e. the same as a switch. If the map you're using is a binary tree, like in cpp, the runtime complexity for lookup is O(n), because here acutal iteration takes place. If it's a binary search tree, it's O(log n).
In the end it really depends what programming language you're using and what underlying structure is used for the map. Switches are safe bet, because their implementation doesn't vary between programming languages as to affect the performance, and it's the most memory efficient option. In addition, it allows easy implementation of "fall-through" behavior.
In Java however, a HashMap will usually be as performant as a switch, and might even be faster depending on how you use it. This again depends on what your JIT does with your Map or Switch.
There really are no easy answers here. The safest bet is try both, check their performance and then go with the faster option.
Please, don’t. This is very inefficient. From the stackoverflow
“Switches will always be as fast as if not faster than hash maps. Switch statements are transformed into direct lookup tables. In the case of Integer values (ints, enums, shorts, longs) it is a direct lookup/jmp to the statement. There is no additional hashing that needs to happen. In the case of a String, it precomputes the string hash for the case statements and uses the input String's hashcode to determine where to jump. In the case of collision, it does an if/else chain. Now you might think "This is the same as HashMap, right?" But that isn't true. The hash code for the lookup is computed at compile time and it isn't reduced based on the number of elements (lower chance of collision).“
Implementation will vary from language to language, but this is generally correct. Also if you ever find yourself using switch case on a string there's a decent chance it should actually be an enum.
There is no need to ever worry about such cases. Focus on readability. If you need optimization, go for it after you identify problems.
@@squishy-tomato no wonder new app take up so much ressources...
@@luxraider5384 Don't worry about it, next year we will have a new iThing with a 100% faster CPU so you won't notice the lag when scrolling down a list of text boxes :)
For this example, yes a switch statement seems overkill. But when you need to do some computational logic before returning something, or maybe you don't want to return at all, absolutely use a switch statement. In some situations, it makes sense to. It's simply false to say "SWITCH STATEMENT ARE BAD" because some situations require it.
Exactly. At first i was interested but then reralized it was about a very specific case.
If you do this in c-type languages, you trade O(1) for O(n) or O(log n) (av. lookup runtime complexity of binary tree, and binary search tree respectively). A hashmap would be the only option I know that can compete with switches in terms of look-up speed. Safest option is always: try all options and use the best one. And by try I mean: also try server-side and client-side performance, if you use a programming language that uses JIT.
Two points:
1: While not the greatest for readability or code quality, C style switch statements are FAST, and in a performance intensive environment, that could make a measurable difference depending on the amount used throughout the code.
2: If you want to do any type of conditional logic based on the compared value, you may as well just use a switch in any case, as you will need to do the check on the returned value anyways.
IMO, there's nothing wrong with the switch case method, since it's much more flexible. The map approach is indeed cleaner if we just want to return a value response, but it's not going to work for anything that's more complicated like we have to do some evaluation/calculation/etc. In any case, it's a good advice nonetheless. Just my $0.02
This is a great point I should have mentions, my mistake. Thanks for sharing Paul 🔥🙏
@@FlutterMapp bro, do you know how much more memory hash maps use??? a switch statement will always be faster and more efficient
Using object literals instead of switch case blocks using logic instead of simple logic for languages like JS is quite simple too, as you can encapsulate each block logic in a function and assign it as object literal values, then, simply invoke the matching key function.
I'll be thrown out of window (y'know the meme).
switch (number) {
case 1: return "one";
case 2: return "two";
}
return "many";
Same number of lines. Works with almost all C-like languages. No extra memory required for container.
😂😂 funny meme 😂 Obviously this video is a little bit over exaggerated. It's cool to know some funky ways to replace the typical Switch statements tho 👏
@@FlutterMapp did you know in c# you could use switch like:
return switch EXP {
Cond1 => true,
Cond2 => false
Cond3 ^ Cond4 => true
}
switch allow you to choose not to break a case, which map doesn’t.
Such as this sample:
const num = 3
switch (num) {
case 3:
console.log(`${num} is larger than 2`);
case 2:
console.log(`${num} is larger than 1`);
case 1:
console.log(`${num} is larger than 0`);
break;
}
When this is run, it will print out all 3 lines of string to the console, since we didn’t break the upper ones.
This could be useful in some situation.
There was no need for the caffeine variable though, you could return inside the switch in each case and that'd be like half the code anyways... 😅
true 😂 That could have been even more refactor, dammit 😂👏
This is a great tip but I'd recommend creating a constant map outside the function if it is independent of function inputs also enhanced enums can be used but for simple use cases it makes the code less readable and unnecessaryly complex
I like your advice Tech buddy. I also suspect that this will be a much better option in terms of performance.
I prefer declaring vars only within the scopes they're used, even if they're const. And if the only scope available is global, I use block-scoping to limit the lifetime of the var. This makes it easier for garbage collectors to reduce memory use, and adds context to names (reducing the need for long names), it also reduces the cognitive load because there's less vars to work with, and reduces scope/namespace pollution.
Of course, the downside is deeper indentation. I wish there was a lang where var scoping didn't require indentation to make it readable. Rust has the `drop` fn, but it only works on heap-allocated stuff, not stack frames
@@Rudxain sounds instead like you'd possibly increase the amount of GC runs and reducing performance instead. Which is ok I guess depending on what kind of program you are doing
@@Erlisch1337 True. Sometimes it's ok to declare constants outside of a function, if the constant is heap-allocated and contains more than 256 bytes of data. This is specially useful if the constant is required by more than 1 fn, and guarantees that only 1 allocation is performed (instead of relying on the optimizer)
This makes sense unless you’re writing C code where you’d have to build your own map struct and put it in an array and it wouldn’t be nearly as visually appealing
On a resource limited embedded platform the switch/case form would be preferable due to the much smaller code and data generated by the compiler, compared to a std::map with its internal binary tree implementation. A switch/case will often be implemented by the compiler as a simple jump table.
My MO is: if I want different functionality I use switch case, if I just want data I use a table/map that just stores the data
Strong disagree with switch statements being bad. Imagine you use an object literal mapping, and then realize down the road you need logic to be executed within one or more of the switch cases. What then? Switch/case is designed exactly for the scenario you gave here and is almost objectively "easier" to read because it's literally telling you "When the case is that a variable is X, execute the below code." Which is more syntactically readable than chaining if statements.
The code is more compact but takes longer to execute because the CPU has to run through an algorithm to find the text string within the dictionary.
What's more important, CPU time, or your time scrolling down a few extra lines of code?
The moral of the story is: *ALWAYS* think about the run time performance of the code you write, and decide if it matters to your application or not.
you seem to have no clue of how hash tables work....
switch case speed is a far more efficient approach, with really huge speed difference
How about using the enhanced enum instead?
I think it will be better and avoid mistyping the key
Sadly they aren’t supported in some language. Dart/Flutter for example added support for that just in the last 6 months
What if we want to call a function? And do something more complicated stuff, instead just print a string. In this case, it doesn't work.
"What if we want to call a function?" You're asking too many questions. That's how people disappear.
"The CIA wants you to think that the switch statement is the same thing as if-else-if chain. It's not. Switch is the most powerful construct in the C language"
- Terry Daves, reworded
Plus it’s scalable and faster with larger datasets. Switch statements do have their uses, and maps have their separate uses. Know when to use each of them
This is only works for functional value returns like shown. Switch case still useful if the switch case is about different ways of execution or algorithm.
Also not all programming language have complete feature set of Map like shown, either lacks or not supported at all.
But still though. Amazing awesome yey thancc
switch statement is not bad.
code readability always rely on your current architecture and structure.
in your sample it looks clean because the process is simple, but when we talk about different problems like an OOP model that follows DDD event mutations then definitely hash map will not work at all times, we need the switch statement to make the code more readable.
eg.
abstract IDEvent
class ShipmentCreated extends IDEvent
class ShipmentDeparted extends ..
class ShipmentArrived extends ..
... etc events
class Shipment
// private fields ...
void apply(IDevent e) {
switch(e) {
case ShipmentCreated:
// mutate private fields
break;
case ShipmentDeparted:
// mutate private fields
break;
case ShipmentArrived:
// mutate private fields
break;
default:
throw NotSupported(e);
}
}
I benchmarked switch vs. std::map in C++. The map is over two orders of magnitude slower. Although that may not matter if your calls are not in a critical loop.
Switch case with strings almost always compiles to a big ‘if else’ block.
Switches with strictly numeric values will optimize to an array or to raw jmp statements, which is a lot faster than if else or map.
But ... it works only when you want to return directly a value in the switch, switch are usefull for many other cases
TL;DR
Use switch case if you have no default value and your type is enum.
TS;WM
Switch might actually be useful, if you're not using a "default value", because map doesn't track null appearance. Switch case lets you know when you're not covering all of the possible outcomes. Not particularly useful for your example, since your type is a string that can be just about anything, but in case of enums it is ideal.
i mean... in that specific case, it makes sense, but it depends on a situation
like when you want to execute more complex instructions, you can obv always have some array of functions and execute the right function or whatever, but it doesn't always make sense to do it
Yeah... he just said "don't use switch as a lookup table"... which i'm sure switch isn't meant to be anyway.
Nothing stopping you putting the case, statement, and break all on the one line for compactness; with tabbing to align them vertically for readability...
You can also arrange case statements and their code on a single line each, greatly improving readability close to a map.
Cleaner yes. How about efficiency/performance?
Ah yes, dynamically allocating memory for a map is totally worse than a jump table.
What you are looking for is something like a switch expression, but I have no idea if Flutter has that.
It’s attractive to the eye but older devs that see memory leaks as a possible issue this technique isn’t gonna look great, in js the object looks very simple but this wouldn’t be so popular in a hashmap. I’ve seen this endlessly in js projects and when it scales up we end up with constant.js files with dozens of js objects, not sure it’s the most optimal thing either.
Sometimes a case can contain non factorable code or maybe other functions calls
This is really depend on language your using , There's nothing wrong in using switch statements and sometimes you don't even have a choice just to use them, in c++ using switch statements is consider to be good than using if else when dealing in big enumerated value. I rather choose switch statements rathen than using map, or any other storage type.
Nice, but I preferer to do some like this: const getCaffeine = (brand: string) => ({ 'Coffee': '95 mg', 'Redbull': '147 mg', 'Tea': '11 mg', 'Soda': '21 mg'})[brand] || 'Not found'
What happens when I have to call a function inside of a switch statement. How do you map a string to function?
But initialize a map object for each getCafeine execution is not good. Switch is build on compilation time and your map on execution time. I agree to write a cleaner code, but not beyond the point to sacrifice performance.
what if the value from a switch statement may come varying functions that require varying parameters, such as deserializing something including its context
What do we write if two different types should return the same caffeine value? Do we need one line for each type or can we say something like (type1 || type2) : '10mg'
Normally when using enums, I prefer to use switch, due to if someone add a new value to the enum, the switch will warn that it needs a new case
Just use an enum instead! It's basically an integer, so it's N times more efficient than a string comparison and the difference will show when you have thousands of entries
This is really helpful! Some languages don't have support for enhanced enums, unlike Dart. This technique can be used there!
Thanks for the video Louis!
Pleasure Rivaan!! Thanks for the support! We need to talk youtube more often! 😂👏 How is going your channel?
map requires knowledge of map and its layout, switch is vastly more understandable by more people and is perfectly readable, even if it takes up more lines, and is faster.
i find this solution less readable xD
like the normal if more and there is no need to declare a var caffeine if it only gets returned so i would do:
if(type==='Coffee')return '95 mg'
if(type==='Redbull')return '147 mg'
...
return 'not found'
so you always see that type is the thing you are looking for, if the list is long.
Object attribute look-ups may be slower than a switch statement.
Another benefit you’re not taking into account is that switch statements in combination with an enum are exhaustive (as long as you don’t use a default case).
Either you don't know what you are talking about or I don't. How can using a map replace the functionality of a switch? A switch case is NOT a data structure. You are treating it as though its purpose is to store data. It is a conditional statement (like if statements) where you can run whatever code you like if a certain case-condition is met.
You could one-line each case with a return and it would be pretty clean, imho.
everyday someone leave from project, someone read others code, no harm to use switch which is common in all language, but not ??
For the cases where we just return a value this seems nice, but when there is logic involved, then undoubtedly switch is the to go to solution.
This is not necessarily good advice. Using a map internally hashes the keys. Which is more work.
Instead switch case guarantees direct access in most languages.
Depends on the use case, but for most part switch case should work.
Or you can just a type Coffee with an abstract function _getCaffenine_. Then you create subtypes.
This will be featured in language conferences. This means it will blow up someday. Please do not flag this as misinformation even though it is.
BTW FYI dart documentation is not supposed to be your 1st langauge. If unvoidable, learn some other close-to-metal languages and data structures, so you won't end up making something like this.
Why ppls always shows the most bulkiest way when showing a switch? If you just simply return from the switch directly, the first code snippet would look pretty good already whitout sacrificing the flexibility of using switch.
If you don't make the map static, it will sort its elements every time the function gets called.
Am I the only never use switch-case?
Use if-else everywhere
I feel like that code is cleaner for simple things like returning a string, though if you want more complex functionalities Switch statements still seem to be the way to go, their structure seems much better for more complex functions.
Dont like this type of "Never do this again" in this particular case you are right but someone could interpret it as "switch case is bad" when it is just a tool. Programmers often have the problem of "when you have a hammer every problem starts looking like a nail". No tool is good or bad but they have different use cases so just learn that they exist and how they work so when you find a problem you can choose which tool is better suited for the job.
This is bad code masquerading as good code... careful, these are not equivalent and in just a tiny more complex examples (run functions in the values) would have got jump back to switches since these are not evaluated until called.
And the String "caffeine" isn't needed and it's only there to make the hash map example viable.
this completely fails once you want to do anything other than simply return a simple lookup value (which anything similar in effect to an associative array will work fine). there's nothing wrong with switch statements, but there is something wrong with telling people a certain coding structure is bad for some arbitrary reason
Now you are allocating memory for the map.
you can do the very same thing with functions, it's quite cool
double velocity = 0;
Function car(String action) {
final map = {
'stop': () {
velocity = 0;
print('car stopped');
},
'acelerate': () {
velocity += 5;
print('car Speeding');
},
'open door': () {
if (velocity > 0) {
print('cannot open dor');
return;
}
print('dor opening');
},
'change gear': () {
if (velocity > 0) {
print('cannot change gear while stopped');
return;
}
print('guear changed');
},
};
return map[action] ??
() {
print('cannot do that');
};
}
car('acelerate')();
Sure, that is cleaner, but dataflow isn't how switch is meant to be used, anyway; it's for controlflow. Using switch isn't always bad.
The switch statement was not invented for this use case, that's why it looks bad if compared to a map or an enum. It mainly used when the logic performed by the program is different depending on the value of the variable the switch is applied to.
Or use dynamic dispatch?
You should never use strings, they're bad practice; rather you should use morse code stored within a bitmask.
Interesting. In my new project, I was thinking about using switch statements instead of super nested if else statements, but maybe this is a much better solution. 🤔🤔🤔🤔
Let me know if you end up using it 👍💪💪🔥
Keep in mind that this solution has a drawback compared to switch-case statements, especially when used inside a widget tree. Instantiating a map with a considerable amount of data or widgets inside it, will increase the usage of memory and decrease performance.
Also: The example shown in the video could be more readable without removing the switch-case statement. Just return the value directly instead of using the String caffeine and you're down to just 12 lines of Code instead of 20.
This video completely ignores the fact that switch statements can be used for executing blocks of code and not just mapping values. Yes, the map is better for this case but is definitely not the solution to all switch statement usages.
Thanks that was pretty fun to learn!
Both are bad. Make a Drink type, give it a "Caffeine" property, and call it that way. Alternatively, make an interface and make a class per drink(in case you require complex computations specific to the drink).
Then, you can easily expand it with the use of a database, which will make it easy to compute even thousands of cases.
Since when hardcoded string is good practice?
That's not exactly the case if the language doesn't support automatic fallthrough, in C/C++ the two cases would pretty much compile to the exact same thing but that supports automatic fallthrough, in C# the switch would likely be very slightly more performant and it doesn't perform automatic fallthrough however the break is still required (which is stupid honestly, why eliminate it but keep the requirement for the break?) making it better to use the lookup table in C# in such a simple case. In other languages it depends but if they perform automatic fallthrough or requires breaks anyway it is easier to read the lookup table.
Bruh imagine allocating space for a hashmap that'll immediately be deallocated on return because you think switch statements are ugly
Why do you declare the String before the map (totally unnecessary), and why isn't the map a static variable? You have no idea what your compiler is going to do, but it might create than map with every call to the function. I did some tests in a few languages, and sure enough, without static declaration, your map is created with every iteration of the function.
You did what's in msg1. I did what's in msg2.
from random import choice
from timeit import timeit
letters = 'abcdefg'
candidates = letters + 'hijk'
lookup1 = dict(map(lambda x: (x[1], x[0]), enumerate(letters)))
def msg1(name: str):
lookup = {
'a': 0,
'b': 1,
'c': 2,
'd': 3,
'e': 4,
'f': 5,
'g': 6
}
return lookup.get(name, -1)
def msg2(name: str):
return lookup1.get(name, -1)
if __name__ == '__main__':
print(timeit(lambda: msg1(choice(candidates)), number=1_000_000))
print(timeit(lambda: msg2(choice(candidates)), number=1_000_000))
Output:
0.3260329579934478
0.2109164169523865
Your technique is 50% slower than the static map.
Just do this:
_caffeine_map = {
....
}
def getCaffeine(name: str) -> str:
return _caffeine_map.get(name, 'Not found')
No risk of reinitializing _caffeine_map if your compiler / interpreter is crap, no redundant variables (which most IDEs - at least JetBrains ones - would warn you about), and more concise code. This could easily be done in most programming languages.
I'm not a JavaScript user, so maybe the const equates to static, but I'm not convinced.
I mean, sure. Using an object is great. But making the blanket statement that switch-case is bad, is pretty bad. Embedded C programming really benefits from the compiler optimization of using switch-case for smaller footprints.
Java has alternative variant
like
switch (variable) {
case 1 -> doSomething();
...
}
I dont think that its "better to read" that just a matter of taste. The Switch statement therefore has the advantage that you can put addtional / extra lines of code to individual cases because you can place as many lines of code as you want between case XY: and break; but if you get the case that you have to implement an addtional-extra behaviour to a specific case you are rewritig the function to the switch-statement to fix this. :) // In the very-base cases its not hardcoded at all but dynamically set-up by a database and modifyable by options dialogue.
I don’t think switch case is not clear…
It’s very clear and readable😑😑😑
I didn’t know people use switch statements to returned mapped values.
Have you ever heard about enums ?
If you are gonna make a list of choices you are better off making a actual code that is a list, not a list of codes.
Make a tuple or array and put your options in there as a condition to trigger while using if else statements elsewhere for the action.
Isn't it better to create a new field in your objects with caffeine amount?
But what if I want write faster code?
If you can't read switch statements by the time you reach data structures then there's something fundamentally off with your programming foundation.
I almost never dislike videos but I disliked this one because the title is just wrong.
I just clicked on this because it uses switch statements - and I use those a lot.
This is actually something I'll be using in my day to day programs!
Switch case is faster than lookup so think if performance is important to you.
If you need to do some calculations depending on the value, you'd be back where you started with a switch statement.
There's nothing bad about switch statements in the example you provided!!!
more vids like that pls, rly good one
Thank you very much! 💪🔥🔥
I learned much more from the comments than the video
If only I wasnt a simple c programmer
This is fine for readability and HORRIBLE for performance. I don't know what language you're using, but any compiled language will optimize a switch statement into a jump table, which is way faster than allocating a map on the heap, initializing it, and then binary searching through it to find your value. Your technique also kinda falls apart if you're doing any actual work in the switch statement, because then you have to pull that out into discrete functions (or lambdas) and put references to that in the map, which is probably good practice but also probably doesn't make things much if any easier to read.
I guess the performance hit goes away if the map is only initialized once, rather than every time the function is called, but that's not what you did in this example.
Why are people saying that switch statements are ugly? They are literally better than if else. Also this example, as several people mentioned, has unnecessary breaks inside of the switch. Is this some sort of a switch slander video? Trying to defame us???
C by default implements hash in switch statements good to see y'all catching up
Interestingly, I have always used for these purposes enum
I'm not sure you needed to explain in detail how the Switch Statement works considering that your target audience should be people who are using the Switch Statement because they know how to use it.
You make a good point under certain situations such as the example provided, but it's terrible advice if taken as a general rule. The video title isn't helping anything either, giving the wrong impression that switch statements are never useful.