Search Unity

C++ < C#

Discussion in 'General Discussion' started by kingcharizard, Aug 27, 2012.

  1. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Bull, that's not the same problem at all. You were talking about the standard practice of writing tons of #ifdef'd header files for everything, which is necessary in all but the most contrived cases like the one above. There's no way to manually ensure declaration in the right order in all cpp files so that you forgo the need for forward declarations, and manually including forward declarations of everything from one file into another file without headers is a nightmare of ballooning redundant code. Most C++ projects are full of those annoying #ifdef'd headers. Or at least #pragma onces. Either way, it's an annoying and mostly useless "feature" of the language.
     
  2. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Then let's go with the World of Warcraft servers and their petabytes of data.


    How would you store all that item and player data without using a database or pseudo-database? Let's say you have a million items on an auction house, and a player wants to search for "Maces and Swords that are between level 10 and 15 and have a buyout price of less than 3 gold". How do you do this?

    How do you preprocess every single potential auction house query? In WoW's example, this is a near infinite amount of queries, given the ability to input integers for various query fields.

    I agree that it's in C++, but they undoubtedly use SQL and T-SQL for all their queries, not precomputed base C++ caches. Of course that code was written over a decade ago, before LINQ existed. If I were doing the same thing now, LINQ would be an ideal solution.
     
  3. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    I'm not saying RAII is a bad paradigm. It's certainly useful, especially in the one case you keep harping on: where a constructor throws an exception after grabbing a file handle. However, basing your entire support of a language on that one contrived example is ridiculous. First, for almost all the common non-memory resources, you will be using a .NET Framework class and not a custom IDisposable anyway. There are existing classes for all kinds of streams, files, network connections, database connections, etc; all of which are extendable and handle their own constructor exceptions safely because they've already written that try/finally that you're dreading. I'll echo ronan and npsf in that I've written a ton of C# code for all kinds of projects, and I've hardly ever had to use IDisposable or needed to worry about RAII. I've also played a lot of games and used lots of apps that hold onto their file handles for a long time while the app is running, and it's generally not that big a deal that I would switch an entire language over just to ensure that a player can open and edit my game's mp3 files while the game is running. I think games are, in fact, one example where file handles are rarely that important; most of the time you'll be working with your game's own files (which the user or other processes shouldn't be messing with anyway, especially not while the game is running) or game save files (which again, the user and other processes probably shouldn't be messing with at all, especially not while the game is running).
     
  4. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    And even then in cases where you don't want to hold on a file handle, you probably want to do a single unit of work on it, in which can you can use the readall/Writeall methods on System.IO.File and not worry about the underlying streams that get created and their initialisation / desctruction
     
  5. laakerules

    laakerules

    Joined:
    Aug 29, 2012
    Posts:
    153
    Ruby beats all, thats final! :p jk
     
  6. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    Derailing a derail of current derails, no fair! :(
     
  7. Morning

    Morning

    Joined:
    Feb 4, 2012
    Posts:
    1,141
    Ruby is on rails.
     
  8. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    Like I said, I would use a real database for that, not LINQ.

    That is not really game play, and it would happen server side anyway.

    There are MMOs getting made every day, if it is truely the 'ideal' solution, perhaps you can point me to some which actually use LINQ instead of SQL.

    The point I am getting at is databases have their place in games, I cannot see a use case for LINQ at all. If you need a database just use the real thing.

    The comparison is between real game technologies and LINQ. You are the one that has repeatedly claimed that LINQ has a place in games, I am just trying to understand where you think that place is.

    It seems to me that if you want to do work on large data sets server side you would use SQL, if you want to manage data on the client side you would preprocess that data and save yourself the computation time. There doesn't appear to be any use case for LINQ in game development.
     
  9. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    I gave you the set of use cases long ago, i can't be any clearer as, as i've said, the answer is "almost everywhere".
    This is why i don't want people mixing linq to SQL in here, whole diferent issue.
    Saying you wouldn't use linq because everything is "pre processed" is like saying you're not using C++ because everything is "pre processed", no not everything is preprocessed, else games would take up 0 CPU time, and almost anything that takes cpu time, is working on a set of data and doing something more trivial than i++, so for a lot of those cases, LINQ is a good tool for the job, i can't name a specific because there are no specifics, it's literally EVERYWHERE.

    If i coded a physic engine in C#, most of it would be in linq, if i coded a graphic engine in C#, most of it would be in linq, if i had to access database data, and retrieved it using linq to SQL, whatever i did with it after would be in LINQ to objects, for pretty much anything i had to do, LINQ has been the right tool for the job, but most everything i have to do is not as simple as "lets see which is the fastest to increment this int to 100000!", so to prove it we'd need a real (at least 500-1Kloc) sample project with a real goal to show the performance / line of code / complexity / maintainability / modifiability ratio between raw C++ algorithms, and C# with the LINQ api and the C# 3.0 features.
     
  10. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    And, since you are using a real database, why not query it with LINQ?


    That is not really game play, and it would happen server side anyway.

    I write games.

    I use 'real' DB's in those games.

    I use LINQ to query those DB's.

    Next!


    A bunch of developers are saying they use LINQ in game dev... so what's the basis of your claim?
     
  11. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    I'm starting to think you don't know what LINQ actually is. It's a query syntax; you use it with whatever data source you want. You don't choose LINQ "or" a database, you use LINQ with a database, with SQL or whatever other data source you want.

    So what, server side doesn't count? Most games these days have multiplayer; it's a little silly to now say we have to limit ourselves to single player games only.

    It's not an either/or. However, your earlier assertions, that you would never need any sort of queries or database and would do everything in precomputed base C++ structures, actually is an either/or.

    As for companies that use it; I, like you, have no idea what half the game companies out there use as far as programming languages. I've worked at Microsoft, and there, we use it extensively. A ton of the backend of Halo 4 is in C# and uses LINQ. I believe Guild Wars 2 does a lot of their server code in C# with LINQ as well.

    I find it insane that you think there's no place you would want to sort or query or select or merge any sort of data in any game. It's like saying "You keep repeatedly saying that the for loop has a place in games, when it would be much better to write out every line of a loop without using for". Anyone who uses C# a lot is going to use LINQ a lot. You must have not used C# very much, because I can't imagine writing queries without it.

    Again, first, you don't actually know what LINQ is and apparently have never used it, so I suggest you look it up on wikipedia or something. Second, you can't "preprocess" every single conceivable query on a dynamic data set any more than you could "prerender" every single frame of a dynamic 3d game. Let's say you want to let the player sort the items in his inventory by alphabetical order or weight, and choose to show only the items that are better than his currently equipped items (think Skyrim). Do you keep a precached list of every possible combination of items in both orders? Of course not... once you get to something like 50 different items and 10 inventory slots, you hit a combinatorial explosion, and you'd need to hand-write something like a trillion different lists, and then store all of those in memory. No one would do it that way. You would store the inventory as a list, and then sort it and query it on demand.
     
  12. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    This is quite simple and no need for a wall of text. Whether I know what LINQ is or not completely irrelevant, I put the challenge out there to all the LINQ evangelists to provide a use-case for LINQ in games. That means providing a problem which is solved better by LINQ than a normal data structures or a full scale database. After several pages of preaching not a single use-case was provided.

    This thread is dead and buried.
     
  13. flaminghairball

    flaminghairball

    Joined:
    Jun 12, 2008
    Posts:
    868
    Here's a common use case: Find the GameObject with a given tag that is nearest a given point.
    Here is a (theoretically - typed in browser) working implementation:

    Code (csharp):
    1.  
    2. GameObject NearestGameObjectWithTag(Vector3 testPoint, string tag){
    3.   var allObjects = GameObject.FindGameObjectsWithTag(tag);
    4.   GameObject closest;
    5.   float currentDistance = Mathf.Infinity;
    6.   foreach(var curObject in allObjects){
    7.     var dist = (curObject.transform.position - testPoint).magnitude;
    8.     if(dist < currentDistance){
    9.       closest = curObject;
    10.       currentDistance = dist;
    11.     }
    12.   }
    13.   return closest;
    14. }
    15.  
    And here it is in Linq:

    Code (csharp):
    1.  
    2. GameObject NearestGameObjectWithTag(Vector3 testPoint, string tag){
    3.   return GameObject.FindGameObjectsWithTag(tag).OrderBy(x => (x.transform.position - testPoint).magnitude).ToList()[0];
    4. }
    5.  
    Now what if you want to find the nearest n objects? Say hello to lots more boilerplate code in the previous function, whereas using Linq:

    Code (csharp):
    1.  
    2. List<GameObject> NearestGameObjectsWithTag(Vector3 testPoint, string tag, int count){
    3.   return GameObject.FindGameObjectsWithTag(tag).OrderBy(x => (x.transform.position - testPoint).magnitude).Take(count).ToList();
    4. }
    5.  
    I won't bother taking sides in the C++ vs C# flamewar - however there is a very real use for Linq in humble game development.
     
  14. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    Now we are (finally) getting somewhere. This is exactly what I wanted, a practical use case to discuss and this is a great one. Thank you!

    This is a very expensive operation, and your implementation does additional work in creating the sorted list so I think the equivalent C# code would look more like this:

    Code (csharp):
    1.     GameObject NearestGameObjectWithTag(Vector3 testPoint, string tag){
    2.       var allObjects = GameObject.FindGameObjectsWithTag(tag);
    3.       SortedList<float, GameObject> list = new SortedList<float, GameObject>();
    4.       foreach(var curObject in allObjects){
    5.         var dist = (curObject.transform.position - testPoint).magnitude;
    6.         list.Add(dist, curObject);
    7.       }
    8.       return list.first();
    9.     }
    It also looks like your LINQ code would evaluate .magnitude more times unless it has the smarts to cache values internally.

    Granted it is more verbose than your one liner, so as far as verbosity for the naive implementation LINQ wins that battle. It is important to note that this an expensive operation, and more often than not the naive implementation will not suffice. The naive implementation is an O(n) operation*, this can quickly become prohibitively expensive as the game grows.

    This problem would be better solved by other means such as spatial partitioning. This is where the issue with LINQ arises, if you want to truncate the search space to speed it up, then you're adding boiler plate and it's not that much prettier than the vanilla C# solution.

    * When you consider the sorting it could be O(n log n) or O( n^2 ).
     
    Last edited: Oct 30, 2012
  15. flaminghairball

    flaminghairball

    Joined:
    Jun 12, 2008
    Posts:
    868
    While I see your point, there are still two very common and (I would say) valid cases:
    1. Rapid prototyping. In my own experience, the linq way of doing things is closer to how my brain works, so not only is it less lines of code, it's lines that are easier to write.
    2. Small-ish games that a) don't need four cores of processing power or b) have other more pressing bottlenecks.


    (Tangential: If we're worried about performance we should be doing the obvious thing first and using sqrMagnitude)

    Anyhoo, I'm certainly not a linq evangelist - I hate linq abuse as much as the next fellow (unless it's for recreational purposes) - however, this was simply one of many potential things that can be made that much easier using linq.

    Cheers,
     
  16. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Not to be pedantic here, but there's been similar examples in this thread for 46 days... what is the difference between them?

    I think it's important to note that anyone who randomly claims some code is 'expensive' and needs a 'non-naive' implementation without knowing any context is probably blowing smoke. If and when you can actually determine it's too slow *then* you can change the implementation to a faster, more verbose alternative. Until such time sticking with the shorter, cleaner more expressive version makes sense.

    I particularly like how your solution:

    This problem would be better solved by other means such as spatial partitioning.

    Could easily slow this down - it all depends on the context.

    Actually [baring a small error on his first example where he uses .ToList(){0] instead of .First()] there are no sorted lists created. This is an example of where in one's rush to do something themselves they rush into it and forget the basics. Under the LINQ implementation* all the items should be streamed - you get the first x objects in order and no more. Under your alternative you create a list that is n long - wasting computation and memory [then needing GC to fix].

    * Technically speaking the default orderby in Linq to Objects isn't streamed [thanks MS!] but there are streaming alternatives online.

    .
    Actually no, this is where LINQ starts to really shine.

    You decide that instead of using an array you want to write a spatial partition that's so fast it finishes the task before you ask it to - awesome! Guess what? As far as LINQ is concerned, and assuming you put in the little additional effort required, the array is an IEnumerable and your new spatial partition is an IEnumerable! So it's very easy to use the performance benefits of custom collections with all the goodness of LINQ - grouping, sorting, projecting, filtering etc.
     
    Last edited: Oct 30, 2012
  17. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    I agree completely on both points. For prototyping and small scale games LINQ can be quite useful. The problem in this thread is that people were not willing to recognize that limitation.

    Yeah, I noticed that too.
     
  18. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    Because there is no such limitation, once again you suffer no (zero niet) performance from linq itself.
    Also you see the obvious advantage of linq as soon as you do something non trivial, for exemple take the previous query the poster mentioned and change it to something like "i want to find the nearest 3 units of the same type (ranged or melle) that are on my side of the game and within the rectangle i drew, excluding units that have spawned within the previous frame to avoid miss selecting, and ignoring already selected units. With linq each of those requirements translates to 1 statement, while procedural code will get more and more complex (as it gets either split into more functions, or more nested).
     
  19. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    case in point
     
  20. Christopherwilde

    Christopherwilde

    Joined:
    Nov 10, 2012
    Posts:
    1
    Nice discussion
     
  21. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Code (csharp):
    1.  
    2. struct Test
    3. {
    4.   // Something contains a thread or socket descriptor so must be cleaned up.
    5.   std::auto_ptr<Something> something;
    6.  
    7.   Test()
    8.   {
    9.         something.reset(new Something());
    10.         *((int*)0) = 0; // access violation exception
    11.   }
    12. };
    13.  
    Will it still dispose something properly? I haven't been writing in C++ since C# came out, so I almost forgot even what header files were used for.
     
  22. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
  23. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    I was just messing around with unsafe C# code in Unity Free yesterday, mixed up two array names by a mistake and got AccessViolationException. I was really surprised when I saw the name of the exception I had caught. In case of C# for the first time ever, I believe.

    I can't say for sure I understand what the correct result of such a request should be, but anyway I doubt the correct query would look much different than this one:
    Code (csharp):
    1. enum UnitType
    2. {
    3.     Melee,
    4.     Ranged,
    5. }
    6.  
    7. class Unit : MonoBehaviour
    8. {
    9.     public UnitType unitType;
    10.     public bool isEnemy;
    11.     ...
    12. }
    13.  
    14. ...
    15.  
    16. IList<Unit> GetNewlySelectedUnits(string tag, Vector3 center, UnitType unitType, Rect rect, ICollection<Unit> recentlySpawnedUnits, ICollection<Unit> selectedUnits)
    17. {
    18.     return GameObject.FindGameObjectsWithTag(tag)
    19.         .Select(go => go.GetComponent<Unit>())
    20.         .Where(unit => unit != null  unit.isEnemy == false  unit.unitType == unitType)
    21.         .Except(recentlySpawnedUnits)
    22.         .Select(
    23.             unit =>
    24.             {
    25.                 var position = unit.transform.position;
    26.                 return new
    27.                             {
    28.                                 Unit = unit,
    29.                                 Position = position,
    30.                                 Distance = Vector3.Distance(center, position),
    31.                             };
    32.             })
    33.         .Where(unitInfo => rect.Contains(new Vector2(unitInfo.Position.x, unitInfo.Position.z)))
    34.         .OrderBy(unitInfo => unitInfo.Distance)
    35.         .Select(unitInfo => unitInfo.Unit)
    36.         .Except(selectedUnits)
    37.         .Take(3)
    38.         .ToList();
    39. }
    I personally don't like long queries. Don't know why, but I like the small ones more:

    Code (csharp):
    1. int totalWeight = inventory.Items.Sum(item => item.Weight);
    2.  
    3. var onlyFoodItems = from item in inventory.Items
    4.             where item.Type == ItemType.Food
    5.             orderby item.Name
    6.             select item;
     
    Last edited: Feb 27, 2013
  24. fbgbdk4

    fbgbdk4

    Joined:
    Apr 10, 2012
    Posts:
    128
    Last year, I made a CSP (Constraint Solving Problem) software, and tried to extract every ounce of performance from my computer.

    The algorithm was tuned to the extreme, and it was in C#. I ported it to Intel C++, which claims to be the fastest.

    Know what? It couldn't beat C#. Actually, the C# garbage collector was doing a faster job than the manual deallocation in C++.

    Moreover, unless I tuned the Intel C++ to one specific architecture, only the C# JIT compiler would take advantage of the architecture specifically in use at that time.
     
  25. _Petroz

    _Petroz

    Joined:
    May 13, 2010
    Posts:
    730
    bad C++ will run worse than good C#. You can write inefficient code in any language. The fact of the matter is C++ is faster if you know how to use it, basic operations are faster, you have more control over memory behavior. If you post the hot spots in your code, I can help you speed it up without architecture specific optimizations.
     
  26. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
    Yes, but there are garbage collection libraries for C++ now, and the coding method you used may have been better suited to C# than good old C++.
     
  27. tasadar

    tasadar

    Joined:
    Nov 23, 2010
    Posts:
    290
    you tuned it for c#. know what? that does not count :)

    c# is nice and fast thats ok but guess which language siemens and dassault systems use for their constraint solver libraries. they do have a point.
     
  28. lmbarns

    lmbarns

    Joined:
    Jul 14, 2011
    Posts:
    1,628
    Unity would suck if it was written in C#. Scripting in C# is great though.
     
  29. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    How basic?
     
  30. JohnnyA

    JohnnyA

    Joined:
    Apr 9, 2010
    Posts:
    5,041
    So in other words you couldn't write a memory handling mechanism in c++ that was more performant than the garbage collection in c#. That's your failing not c++'s.
     
  31. fbgbdk4

    fbgbdk4

    Joined:
    Apr 10, 2012
    Posts:
    128
    The initial code run in 120 seconds, the optimized one in 2 seconds. I'm not saying this is the best possible, just showing some effort was put into algorithm optimization (it barely uses any library, I didn't even used C++ STL and coded my own vector type, since STL was too slow.)

    The boottleneck in C++, compared with the profiler in C#, was the 'delete' operator from the Intel compiler. I could as well make less allocations and increase memory usage a lot, but this was the point I saw it was not worth. (For this much work, it would be better to code in Assembly. :wink: )


    Decades of investment and development is a valid point.

    I had this hands-on approach, and I'm not sure if you also had, so I'll not go into religious discussions. :p

    But don't take my word for that, here is a good stackoverflow thread:

    http://stackoverflow.com/questions/145110/c-performance-vs-java-c

    Some highlights from this thread, that explains better the cases where C++ or C# can be faster.

    Some of the scenarios C# can be faster:

    Some of the scenarios C++ can be faster:

    I'm quoting this because I agree with the author, and he worded it better than I could.

    But I will not go further into this discussion. Just wished to throw my 2 cents.
     
  32. fbgbdk4

    fbgbdk4

    Joined:
    Apr 10, 2012
    Posts:
    128
    Read my post above. Some of the guys at stackoverflow also experienced that. Since I don't believe you had this experience, I'll not discuss beliefs with you.
     
  33. Jens Rasch

    Jens Rasch

    Joined:
    Dec 19, 2012
    Posts:
    76
    I appreciate that trend - if it's true. C# is far easier to learn than C++ or C itself. All these pointers and includes missing in c++. I remember trying to code even a "Hello world" in C++ and it said this or that was missing. C++ is not inviting.
     
  34. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
    I disagree. I actually started with Java first, then moved onto C, then C++, and when I picked up Unity I learned C#. No language is inherently more difficult to use than others (well, except for maybe brainfuck).
     
  35. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
  36. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    Well C++ may not be more "difficult", but it is as he said "less inviting", it having evolved so much and having so many diferent toolchains make it less newbee friendly.

    And while C# has some hard things to grasp (grasping LINQ and labda over the simple "hey it works like sql" is not that simple, even less so if you include RX) C++ is probably much harder to master, not because it should be difficult, but because of the overall mess of the language and implementation dependant stuff. I've never seen someone (beyond newbees who think so) claiming they master every aspect of C++, i can think of a few people who fully master C#.
     
  37. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Are you sure about that? From what I've heard from 'old and wise' developers that even pro with 10 years of experience in C++ will not necessarily have a full grasp on the language because of its scope.

    On the other hand, C# can be learned in full in a couple years should one be inclined.
     
    Last edited: Mar 2, 2013
  38. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    C# is a modern language , it assumes far more and is wayy easier to learn .

    Objective -C is the real hard crap here, I have a mac and I , just can't .... WHY YOU MAKE IT HARD APPLE