Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

367 Neutral

About jods

  • Rank
  1. jods

    c# sorting

    Side-note: is there a reason you use struct instead of class? Doing so usually results in more harm than good. (Especially if you don't master all the interesting differences between a reference type and a value type.) Most .NET sorting and comparing APIs take an optional IComparer interface. Look it up. Or if you don't want to create a distinct class (maybe your records are always sorted that way) you can implement the IComparable interface directly. If you want a quick one-shot solution you may use LINQ: foreach (var item in Data.OrderBy(x => x.personnummer)) // print item Of course using strings to store numbers may not provide the sort order you'd expect. EDIT: Nik02 wrote an answer at the same time as I did. Interestingly they are somewhat different: Nik02 code actually sorts your array structure (and stores the sorted array). My suggestion doesn't modify your array, it only sorts the items for the display operation. Also you should realize that neither way is terribly efficient with big structs.
  2. To the OP: I am not too sure what your needs are, but I think you may be interested in DB4O. It's a database system, which doesn't require SQL, needs next to zero administration, is very easy to use, and has decent performances. It is available under either a commercial or a GPL licence. Have a look here: www.db4o.com [Edited by - jods on November 27, 2006 7:01:47 AM]
  3. Yes, I agree with you that your example is very dumb. It's a classic textbook example, which tries to illustrate how concepts work, but is totally useless. Here's some examples of why pointers are required: 1. Dynamic memory allocations. If you don't know at programming time how many objects your application needs, you can declare them. Instead, you allocate them at runtime. Consider a game, and the player fires a new bullet. You need an object to represent it (position, speed, etc.). You would probably write this piece of code: Bullet* bullet = new Bullet(); bullet is a pointer to the newly created bullet object. Now how do you keep references to an unknown number of objects ? By using data structures like linked lists, vectors, hash tables, binary trees, or whatever suits your requirements. If you study data structures (which you really should), you'll discover that those are using pointers all over the place. And you can't avoid them like you could in your 'textbook' example. Another example requiring dynamic memory allocation could be a mesh loader. You don't know how many vertices/faces your mesh contains before actually loading it -> you need dynamic memory allocation -> you need pointers. 2. Pointers can be more performant than static variables, especially when considering large structures. Let's say you have a function which Inverts a 200x200 matrix: Invert200(Matrix m) If you pass the matrix by value, at runtime you're copying 40'000 elements (maybe doubles) on the stack. Quite a performance hit. If you pass it as a pointer, or by reference (which is a disguised pointer): Invert200(Matrix* m) or Invert200(Matrix& m) then you are only copying a pointer (4 bytes, maybe 8 on 64 bits cpu) on the stack. A huge difference. 3. One usually likes to use pointers to do buffer manipulations. True, you can replace this with an array and an index, but sometimes it's simpler to use pointer arithmetic directly. And anyway, in C an array is just another disguised pointer. 4. Pointers to functions can be use to provide genericity. But this is a little bit different than your basic "data" pointer, and one could argue that it would be better designed by using inheritance and virtual functions, so I won't go deeper into this. Have a nice day, jods
  4. I'm just guessing, because you haven't given enough information to be sure. But here are a few points which often cause me problems: -> when (in the page life-cycle) do you create your controls ? For the events to happen, it must be relatively early. The correct place to do it: override the CreateChildControls method (or something like that, I don't have my dev references here). -> if you want the event to be raised, remember you must re-create your control during the postback, just like it was created when you first sent the page. -> one common cause of trouble when I use dynamically created controls is not setting a control ID. Sometimes it works without, but it often creates problems. -> I see you enable the ViewState, and that's right if you want events. But also check that the Viewstate is enabled for the whole control hierarchy in which your control resides (just like visibility, viewstate is a property which "propagates" to its children when it's disabled). I hope this helps.
  5. I'm using embedded private fonts, too. I feel your pain, because it has been a very long and frustrating experience for me. Apparently, embedded font resources aren't very well-supported, and the feedback I got about my bug reports makes me think that Ms doesn't care a lot about them. I'm using C# 2.0, here's my code to load one font, included as a resource in my assembly: class AnyClass { // This is used to correct a bug in GDI+. // Private fonts return garbage in GetKerningPairs if they are not installed on the system. // Also, they don't print correctly. [DllImport("gdi32.dll")] private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); private PrivateFontCollection pfc = new PrivateFontCollection(); public AnyClass() { unsafe { fixed (byte* pFontData = Resources.MyFont) { pfc.AddMemoryFont((IntPtr)pFontData, Resources.MyFont.Length); AddFontMemResourceEx((IntPtr)pFontData, (uint)Resources.MyFont.Length, IntPtr.Zero, ref dummy); } } } } Note that I've included an interop call to the GDI AddFontMemResourceEx function. I managed to make my program work without this call, but it had two bugs: - trying to get the kerning pairs for the font returned meaningless garbage. - printing didn't work, the font was substitued by another one. I'm accessing the font data with the compiler-generated Resources class. Finally, I haven't tried using this font directly in the GUI (I mean: with the designer), but I'm using it successfully in some calls to DrawString. I hope this will help you. jods
  6. A few remarks: - why are you using BeginExecuteNonQuery ? Unless there's a good reason you should be using ExecuteNonQuery. If you go for the asynch route and use Begin..., then you msut also call EndExecuteNonQuery. And you don't know if the call was successful until you do so. - What type is the field img_loc ? If it's a string, you should quote the SQL value between ' '. E.g.: INSERT INTO myImages (img_loc) VALUES ( 'blabla' ) So your example may be: "INSERT INTO myImages (img_loc) VALUES ('" + File1.Value + "')" - But take great care! What happens if File1.Value contains a ' ? Inserting user input into a SQL command should never be done. Some user input may provoke error (example: "jods' bad input"), and even worst, some user may take advantage of that to attack your system (this is call SQL injection). Example, I suppose syntax is SQL Server: if I enter "blabla'); DELETE FROM myImages; --" I would have erased your whole myImages table. Surely not something you want. The solution is to use SQL parameters. Look it up on google or MSDN. - Finally, seeing your code, I wonder if img_loc is a BLOB. If it is, you should look it up on google/MSDN, because uploading BLOB to a database is usually more complicated than executing an INSERT (there is some specific methods for BLOBs). I hope this helps, jods
  7. Here's how I see the difference between an enum and a const. enum is a new type, which can take a fixed number of discrete values. Often (but not always), the actual values assigned by the compiler to the enum elements doesn't really matter. I personnally think that your USER_CODES example is a good one. Here's another one: enum Alignment { Left, Center, Right, Justified }; const is just a magic value. If you have many related consts, you should consider whether they aren't an enum. Some examples of consts: const double Pi = 3.14; const int MaxNumberOfConnections = 15; const char ArgumentSeparator = '&'; Of course, this may be a question of style, and you can do it another way. BTW: I agree with Arild. IMHO, you should not wrap a constant into a property. At least not if it's a true constant. Regards, jods
  8. Your program is far too aggressive on Windows resources (handles and such), especially for what it does (as I understand it: display a collection of pictures). 400 picture boxes times, say 10 tabs, that's 4'000 boxes... Imagine if every single application used as many resources! I suggest 2 different solutions: 1/ If your layout is simple and there's no complex user interactions: consider writing your own "picture list" control. Override OnPaint and use GDI+ to render it. This way you use only one handle, instead of 400. 2/ If you think that you benefit a lot from the windows infrastructure, and you don't want to use the first solution, you can use virtualization. At two different levels: 2a/ UI Virtualization. Most probably, your 400 pictures are not visible at the same time. I suppose there's some scrolling, and that something like 40 pictures are visible at the same time. The trick is to instantiate just a little more picture boxes (e.g. 50), and re-use those that leave the screen to fill the screen on the opposite side (i.e. you move them and change the picture in it). This way, you use a constant number of handles (which is just slightly more than what is visible on screen), no matter how big your list is. 2b/ Also consider Data Virtualization. It's probably not reasonable to have 4'000 different pictures loaded in memory at the same time (especially if they are big). You can reduce your resources and memory footprint by dynamically loading them, when they are needed. Hope it helps, jods PS: Just guessing: if this is part of some kind of tile engine, you should definitively go with solution 1.
  9. Hi Procyon Lotor, Please don't take it wrong, I don't want to sound harsh... but: you clearly don't know assembly and performance optimization well enough to run those tests. The assembly code you've posted doesn't look optimized for performance at all. And the discussion which follows clearly shows your lack of knowledge about that subject. Let's be constructive and answer some of your questions: -> Yes, you surely can optimize computing intensive tasks with assembly, and I'm sure well written asm code can beat C# for a simple task like testing prime numbers. But to write good asm code you need to know more than just the asm language. You need to know the internals of the CPU. And yes, it changes with every new CPU made by Intel and AMD... Performance optimization for the 386 was a completely different game than for the first Pentium (which had the tricky U and V pipelines), and is still a different game on today's P4. If you want to write optimal code you need to know how the cache impacts perf, how a superscalar processor works, what is dynamic pipelining, what are the differences between the FPU and the ALU, how the decoder works (this explain why loop is a slow instruction), etc. As someone wrote previously, this is more than just a few hints we can pass to you. If you are interested, you have to read some good books about the subject, maybe start with the classical Patterson & Hennessy "Computer Organization and Design". -> That being said, today's compilers know the processor architecture quite well, and they do a good job optimizing code. That's why they beat you. You may write faster code though, since they can't pull out some smart tricks, or do some complex optimizations. -> Now about the code you posted above. There's one big difference between C# and ASM: you're doing double divisions with C# (i.e. on the FPU), and you're doing integer math in ASM (div opcode). This is a BIG difference. I'm pretty sure that if you use the same type in both languages, you'll have roughly the same performance. Because the code you consider is trivial (basically a division in one loop), you should be able to write more or less the same asm code than the compiler, hence having more or less the same performance. -> But there is NO point comparing equivalent ASM and C#. Of course, if you write the same ASM that the C# compiler outputs, you'll have the same perf. What is interesting, is to tune your ASM aggressively for performance. -> What do I call aggressively ? The subject is unending, but here are just a few pointers which show that your code is highly sub-optimal (Here I am speaking about fine-grained optimization, not algorithmic. To be fair, the same algorithm must be used in C# and ASM): 1. Use floating point arithmetic for the division (and float would be even better than doubles, given the job you want to do. But to be fair, also use float in C#). 2. Unroll your loop to maximize parallelism and minimize jumps. I bet this is the biggest optimization that you can do to such a simple piece of code. If you don't know what loop unrolling means: Put something like 8 division in each loop iteration instead of 1. (Do the remaining modulo 8 divisions outside the loop). 3. Using this technique further, you could parallelize your divisions with SSE, but I really don't know if it would be worth it in this case. As often in optimization, one should try and measure to check. 4. Hand-craft your ASM. Some examples: 4a. Minimize the number of jumps and the number of instructions. Someone mentionend that jnz Next2 jmp CheckDone Next2: Could be just: jz CheckDone. Also, Maybe sometimes you could movCC instead of jump (haven't checked carefully though). 4b. It has also been said that you should avoid CISC instruction like loop. dec/jnz are faster. 4c. Avoid lines like inc ebx inc ebx There's a dependency between the two, and "add ebx, 2" should be just faster. Well, that's a start. I'm sure that if you do all those things, your asm version should get faster than C#. But remember such simple examples don't mean anything. As soon as you move to more complex problems, it's getting harder and harder to write optimized asm. Which means: 1. You may not be able to write faster asm than the compiler; 2. It's just not worth the effort. I hope this answer some of your questions. Kind regards, jods Edit: Sorry if most of this is redundant with previous posts. It looks like there has been a lot of posts while I was writing.
  10. For a free, open-source, docking component, look at DockPanel Suite: http://sourceforge.net/projects/dockpanelsuite/ Tim Dawson's SandDock once was free for non-commercial projects, but the "free" licensing option doesn't seem to exist anymore. You can check it anyway: http://www.divil.co.uk/net/controls/sanddock/downloads.aspx If you don't mind going commercial, there are tons of similar libraries, made by companies such as Infragistic, ActiPro, Syncfusion, DotNetMagic, Olivio IT, ... Just google for "Docking"...
  11. jods

    [.net] Drawing namespace ?

    Quote:Method 'pnlA1_click' cannot handle Event 'Click' because they do not have the same signature. Click signature (sorry, C# style): void EventHandler(object sender, EventArgs e) Paint signature: void PaintHandler(object sender, PaintEventArgs pe) So you have to change more than just the name. Quote:If this is the case how can I expect to draw the circle on the panel when the user clicks on the panel? Check out on the internet how painting works in Windows. Otherwise you'll hit the #1 mistake by drawing beginners. To sum it up: Do all the drawing in the Paint event. This will be called everytime Windows needs to repaint the window (e.g. if it was hidden by another window, minimized, out of screen, etc). If you don't, every painting you've done will disappear. When the user click, save somewhere that you need to draw a circle. Then request a repainting from Windows using the Invalidate function. Then, in the paint event handler, do the actual drawing. Hope it helps, jods
  12. jods

    Toughest thing to program

    Quote:Your logic is flawed; how do you know the universe certainly can hold a line? And even if the universe can hold lines, the logic is still flawed. programwizard makes assumptions on the topology of the universe. Consider the surface of a sphere (imagine a worm on an apple). Would you say it's infinite ? Definitively not. But it can hold a line between any of its two points, and appears inifinite to the worm. Same story with the surface of a tore, which is very different from the sphere. Now, these are 2D examples, and our space appears to be 3D. But nothing prevents it to work in the same way (altough it's hard to mentally picture).
  13. Your last message seems to imply that you are manipulating the GUI from another thread. If it's the case: don't do it. From the MSDN doc, the only methods that are safe to call on a Control derived class are: CreateGraphics, Invoke, BeginInvoke and EndInvoke. All other methods have to be called from the thread that created the controls. If you need to call those from another thread, use the Invoke methods.
  14. The sample on this page does just what you want: http://www.yoraispage.com/articles/20040903.asp The trick is quite simple, handle the WM_NCHITTEST message (look it up in MSDN, basically Windows uses it to know in which area of the control you clicked) to make Windows believe that the client region is the caption bar region. You have to use interop for that, since .NET (at least 1.1) doesn't expose messages relative to the non-client (NC) area. Hope it helps, jods
  15. jods

    [.net] Thank you .NET 2.0

    Quote:Original post by Daniel Miller By the way, what do you mean when you say the deadlocks don't look bad? I probably didn't express myself very well. What I wanted to say is that you can create deadlock with calls that really look inoffensive. E.g. just getting a Text property from a control can potentially create a deadlock if you're not doing it from the right thread.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!