Sunday, December 29, 2024

How to link to a file or folder in Apple Notes on Mac?

Step 1: In Finder, select the file (or folder) you want to link to, then press Option + Command + C to copy the path of that file (or folder).

Step 2: In Notes, click Edit > Add Link. In the“Linked to:” field, type “file://” then press Command+V to paste the copied pathname.

Saturday, December 17, 2022

Wrinkle-resistant machine-washable fabric placemats

It surprised me that it was really hard to find fabric placemats that were machine washable AND do not wrinkle easily. (Try searching for it and you'll see.) Eventually, I found it, from BeginninginSTL on Etsy!! Impressively, every placemat was hand-made and shipped from St Louis, Missouri. Here's a direct link to one of the placemat designs. The secret is in the fabric—polyester—which doesn't wrinkle as easily as other materials like cotton. Also, the seller/creator has chosen a variety of fabrics that can go well with different settings. ⭐⭐⭐⭐⭐



Tuesday, July 6, 2021

Best Easy Delicious Desserts for Potluck Party

As a student, I used to dread going to potluck parties because I didn't like how my home-cook dishes (I did like seeing friends at the parties though!). They're just not appealing --- didn't taste good or look good (I would gladly eat them, but just worried about scaring my friends...).

One day, I decided that I had to fix this --- to learn to make one thing that I could bring. Something that's delicious, easy to make, *and* unlikely that other people would bring.

So I found this 5-star Brownie Chocolate Chip Cheesecake recipe.
It needs very few ingredients, and you basically just mix them together, and it tastes fantastic. Brownie bottom layer, plus cream cheese top layer filled with chocolate chips. Yummy. None of my friends could resist. (Mr. V, you should try it, but don't eat so much. Watch your tummy.)

And I'm using this springform pan (Nordic Ware Springform Pan 10 Cup, 9 Inch). Sturdy and doesn't leak. Hasn't failed me for years!


This Christmas, I learned another recipe: Rice Krispies Treat. It needs only 3 ingredients, and 10 min to make (really 10 min, unlike other recipes that lie). Delicious. A good dessert to make when I don't have much time. There's Kellogg's version, but I like my friend's ingredient proportion better:
  • 1/4 cup butter
  • 4 cups marshmallows
  • 5 cups Rice Kripies cereal


I use one of these nicely-built pyrex containers (3 QT) to hold the rice krispies.

Monday, July 5, 2021

Simple healthy meal in 1 minute. No cleaning needed!

Being a PhD student often means having little time to cook, or thinking about what to cook, making trips to grocery stores, hauling home whatever I've bought, deciding on when to cook it (e.g., which day of the week, is it for lunch or dinner?), how much time I need to prepare and cook the food. And finally, cleaning all the cooking utensils!! Argh...

My friends and I often end up eating out, which can really add up (most grad students live paycheck to paycheck), and more importantly it's often not healthy, and you often have no idea what ingredients they use.

It took awhile for me to learn, but I finally found the ultimate way to cook healthy meals where prep work is (literally) 1 minute, and there is no cooking utensils or pans to clean!!

The secret is cooking everything using a single "sheet pan" and put everything you want to cook on it. And that's it! (We assume you have an oven, which is often the case for apartments and houses that grad students living in the US.) 

Here's how it works:

  1. Pick/buy whatever sheet pan that you want to use. Your food actually won't be touching this pan, so its exact material is not very relevant. But if you want to use the pan for cooking other things (e.g., bake cookies) then you'll want to research it a bit (which is out of scope of this post!).
  2. Lay a piece of parchment paper on the pan. Since the paper is non-stick, when you're done cooking, you just throw it away. No need to clean the pan!! Parchment paper usually comes in a roll or as sheets. You can use either here, because our main goal is to simply use it to separate the food from the pan. Some people recommends aluminum foil, which can also works, but your food can stick to the foil.
  3. Put whatever proteins (e.g., chicken thigh, pork chop, fish filet) and whatever frozen vegetables you want on the pan, and sprinkle whatever oil and spices on top. This part is really up to you. As shown in the picture, I usually buy different kinds of big bags of mixed frozen veggies (you'll surely find them at your local groceries), and you don't need to thaw them. Jump dump them directly on the pan. Main reasons are that they last pretty much forever, already "chopped up" (i.e., YOU don't need to do it) and there's no difference in terms of nutrition  when compared to their "fresh" version (and sometimes even better!), and usually cheaper than "fresh" versions (which may not be very fresh after all because they can be in transit for days or weeks!). I usually sprinkle some olive oil, salt, black pepper, and chili flakes. But again, it's really up to you. Experiment and find the tastes that you like (since you're the one eating it)! An a quick note --- it may not be a good idea to wash raw chicken because washing can easily spread germs to utensils and other food (i.e., you can just put the chicken directly on the pan).
  4. Put your pan of food in oven and bake at a temperature and for enough time that will thoroughly cook the protein which depend on the size and thickness of your protein, and the temperature accuracy of your oven. For the salmon in the picture, I used 400F and baked for 20min. Don't worry if you don't get the temperature and timing right the first few times. Think of this as a learning process. And you will eventually get it!
  5. Then pull your cooked masterpiece out of oven and plate it and eat! Throw away the parchment paper. No need to clean the pan (unless you've dripped food or oil on it). Yay!

As you now can tell, the main "cooking" time is really spent on pulling out the pan, placing parchment paper, dump the protein and frozen veggies on the pan, all can be done in under a minute! Enjoy!

Another important benefit, as the title of this post says, your meal is "healthy". You know what your ingredients are and you know the cooking process.



Sunday, July 4, 2021

Best mobile standing desk for small space


Living in a small apartment means often thinking about how to use space efficiently. I like “mobile” furniture (i.e., on wheels) that I can easily move around when needed, say when I want to re-organize my place, or when I just want a change of scenery when working.

As I get older, sitting in front a computer all day is starting to give me muscle aches. It’s time to investigate standing desks! Very quickly, I found most standing desks are rather large and they are NOT mobile (i.e., no wheels to roll on). After a lot of detective work, I finally found a small height-adjustable standing desk that I can easily roll around!

Have been using it for a few years, almost every day. My computer setup is simple: a small laptop connected to a monitor, wireless mouse, and wireless keyboard. All fit nicely on the desk; just enough space for me. The desk is overall very sturdy; the wheels roll smoothly, and the center pillar supporting the table top is solid. Overall, very happy. 

This desk is particularly useful for remote work where I can move it around my place to pretty much anywhere I want!

Convert PNG/JPG to EPS on a Mac for free, without creating a huge file



The command for converting PNG/JPG to EPS are:
convert temp.png -compress lzw eps2:temp.eps
convert temp.jpg -compress jpeg eps2:temp.eps

The convert command comes from the imagemagick package available on Mac, Windows, Linux, and iOS.

If you type only convert temp.png temp.eps, it's gonna create the EPS file without compression, creating a huge file.


Using steamer instead of iron for wrinkles on clothes


 No one likes to iron clothes. It takes so much effort and space. Clearing space in my small apartment so I could open up the ironing board was already a chore. Then needed to wait for the iron to warm up. All I wanted is to just iron one shirt!

It’s only after a while that I learned of a much better alternative — using a steamer instead! Which uses hot steam to loosen wrinkles. No ironing board needed. It's fast to heat up the steam (and it only uses water). It has a small footprint. And since it stands upright, you can hang clothes on it. Plus, you can use it to sterilize curtains and other things. Handy! 

I picked the consumer model from the Jiffy brand with metal “head” (vs plastic head). I like that it’s super sturdy (have it for more than 15 years) and still looks like new (which is in fact not too surprising since there aren’t any moving parts; its main purpose is to boil water and dispense the steam in a controlled manner). I looked up that its a reputable brand and have been making steamers since 1940 in USA.

I wish I knew about steamers sooner, because it’s such a time and space saver! I rarely use the iron any more, the only times I use it is when I need sharp creases on pants, which is extremely rare. The steamer is one of the things that I use almost every (work) day. Before I leave home, I can just pull out the clothes I want to wear, steam them all in less than a minute and I’m good to go!

Saturday, March 29, 2014

How to lighten up a dim room with minimal effort and cost


Get one of these socket splitter to your floor lamp, then add a bulb, to double the brightness! There are now actually many variations, with as many as 1-to-4 split! 

Sunday, October 13, 2013

Template for beautiful Latex table




Latex source copied from
http://www.latextemplates.com/template/professional-table
Great, general design tips from Markus
http://www.inf.ethz.ch/personal/markusp/teaching/guides/guide-tables.pdf

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Professional Table
% LaTeX Template
% Version 1.0 (11/10/12)
%
% This template has been downloaded from:
% http://www.LaTeXTemplates.com
%
% License:
% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
%
% Note: to use this table in another LaTeX document, you will need to copy
% the \usepackage{booktabs} line to the new document and paste it before
% \begin{document}. The table itself can then be pasted anywhere in the new
% document.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass{article}

\usepackage{booktabs} % Allows the use of \toprule, \midrule and \bottomrule in tables for horizontal lines

\begin{document}

\begin{table} % Add the following just after the closing bracket on this line to specify a position for the table on the page: [h], [t], [b] or [p] - these mean: here, top, bottom and on a separate page, respectively
\centering % Centers the table on the page, comment out to left-justify
\begin{tabular}{l c c c c c} % The final bracket specifies the number of columns in the table along with left and right borders which are specified using vertical bars (|); each column can be left, right or center-justified using l, r or c. To specify a precise width, use p{width}, e.g. p{5cm}
\toprule % Top horizontal line
& \multicolumn{5}{c}{Growth Media} \\ % Amalgamating several columns into one cell is done using the \multicolumn command as seen on this line
\cmidrule(l){2-6} % Horizontal line spanning less than the full width of the table - you can add (r) or (l) just before the opening curly bracket to shorten the rule on the left or right side
Strain & 1 & 2 & 3 & 4 & 5\\ % Column names row
\midrule % In-table horizontal line
GDS1002 & 0.962 & 0.821 & 0.356 & 0.682 & 0.801\\ % Content row 1
NWN652 & 0.981 & 0.891 & 0.527 & 0.574 & 0.984\\ % Content row 2
PPD234 & 0.915 & 0.936 & 0.491 & 0.276 & 0.965\\ % Content row 3
JSB126 & 0.828 & 0.827 & 0.528 & 0.518 & 0.926\\ % Content row 4
JSB724 & 0.916 & 0.933 & 0.482 & 0.644 & 0.937\\ % Content row 5
\midrule % In-table horizontal line
\midrule % In-table horizontal line
Average Rate & 0.920 & 0.882 & 0.477 & 0.539 & 0.923\\ % Summary/total row
\bottomrule % Bottom horizontal line
\end{tabular}
\caption{Table caption text} % Table caption, can be commented out if no caption is required
\label{tab:template} % A label for referencing this table elsewhere, references are used in text as \ref{label}
\end{table}

A reference to Table \ref{tab:template}.

\end{document}


Friday, September 13, 2013

My favorite Doodle alternative


Doodle is great for intersecting calendars with collaborators to come up with times for meetings.

However it doesn't provide a fast way to quickly mark time slots for "yes" or "no".
I've participated in Doodle poll that have over 100 slots for me check! Just imagine how tedious it is  having to check off each one...

My new favorite is when2meet.com Excellent user interface! Super simple to use.

Saturday, April 13, 2013

Must read for PhD students

Probably the best few minutes you will spend in your PhD life. Life-changing advice!
How to have a bad career in research/academia by Prof. David Patterson

Monday, January 14, 2013

Shell script to import MySQL dumpfile into SQLite

# Compiled by Polo Chau, by adapting Igor's StackOverflow answer on 
# http://stackoverflow.com/questions/489277/script-to-convert-mysql-dump-sql-file-into-format-that-can-be-imported-into-sqli

#!/bin/sh
if [ "x$1" == "x" ]; then
   echo ""
   echo "Usage: $0 "
   echo "This is a shell script that imports a MySQL dumpfile into an SQLite database."
   echo "Tested on a Mac with OS X 10.8.2 (late 2012)"
   echo "Creates 3 output files."
   echo "1) out.db  -- SQLite database created from the MySQL dumpfile"
   echo "2) out.sql -- a cleaned-up version of the MySQL dumpfile, readable by SQLite"
   echo "3) out.err -- SQLite's error messages generated during importation"
   echo ""
   exit
fi

cat $1 |

# delete the lines containing "KEY", "UNIQUE KEY", "PRIMARY KEY"
grep -v ' KEY "' |
grep -v ' UNIQUE KEY "' |
grep -v ' PRIMARY KEY ' |

# use sed to substitute mysql-specific keywords with general SQL keywords that sqlite knows
# tell sed to read the text as unicode text, by specifying LANG=en-US.UTF-8
LANG=en-US.UTF-8 sed '/^SET/d' |
LANG=en-US.UTF-8 sed 's/ unsigned / /g' |
LANG=en-US.UTF-8 sed 's/ auto_increment,/,/g' |
LANG=en-US.UTF-8 sed 's/ auto_increment/ primary key autoincrement/g' |
LANG=en-US.UTF-8 sed 's/ smallint([0-9]*) / integer /g' |
LANG=en-US.UTF-8 sed 's/ tinyint([0-9]*) / integer /g' |
LANG=en-US.UTF-8 sed 's/ int([0-9]*) / integer /g' |
LANG=en-US.UTF-8 sed 's/ character set [^ ]* / /g' |
LANG=en-US.UTF-8 sed 's/ enum([^)]*) / varchar(255) /g' |
LANG=en-US.UTF-8 sed 's/ on update [^,]*//g' |
LANG=en-US.UTF-8 sed 's/UNLOCK TABLES;//g' |
LANG=en-US.UTF-8 sed 's/LOCK TABLES `[a-zA-Z0-9]*` WRITE;//g' |
# tell perl to read the text as unicode text, by specifying -C
perl -C -e 'local $/;$_=<>;s/,\n\)/\n\)/gs;print "begin;\n";print;print "commit;\n"' |
perl -C -pe '
  if (/^(INSERT.+?)\(/) {
     $a=$1;
     s/\\'\''/'\'\''/g;
     s/\\n/\n/g;
     s/\),\(/\);\n$a\(/g;
  }
  ' > out.sql

# import the cleaned-up version of mysql dump into out.db sqlite database
# errors saved to out.err
cat out.sql | sqlite3 out.db &> out.err

Monday, April 23, 2012

PowerPoint Mistakes -- from a usability standpoint

I saw a presentation today. Some of its fonts were really tiny.
That prompted me to google "powerpoint mistakes". Got many hits, including this funny and informative YouTube video by Don McMillan.

Interestingly, these sources often only tell you what to, or what not to do, but don't really tell you why.
For example, some would tell you "don't read the slides", "use a minimal font size of 24", "don't use more than 7 bullets on a slide", "don't use dark color text on dark background", etc.

But what are the common rationale behind all these dos and don'ts?
Usability -- that is whether it is easy for your audience to "use" (read, understand, see, etc.) your slides.

If you think about your slides' usability as the first priority, then I expect you can naturally fix many of your slides' problems. For example, you won't:

  • use fonts smaller than 24, because audience in the last row of a room can't see the text
  • use more than 7 bullets, slide gets visually complex, straining your audience's eyes
  • use dark color text on dark background, because your audience will find it hard to read
  • read slides, because your audience will find you boring,
  • and the list goes on...

I think it's much better to only remember one thing -- the principle of good slide usability -- rather than having to remember a laundry list of dos and don'ts.

Usability is one focus of within the research area of Human-Computer Interaction. I think it also applies to slide design.

Tuesday, March 27, 2012

Aggregate bitwise OR in SQLite

The following SQL snippet applies bitwise OR on all the values in numbers table's value column. This example supports up to 8 bits; you can easily extend it to support more.

CREATE TEMP TABLE numbers(value INTEGER);
INSERT INTO numbers VALUES(2);
INSERT INTO numbers VALUES(3);
INSERT INTO numbers VALUES(15);

select 
((sum(value&1)>0) << 0) + 
((sum(value&2)>0) << 1) +
((sum(value&4)>0) << 2) +
((sum(value&8)>0) << 3) +
((sum(value&16)>0) << 4) +
((sum(value&32)>0) << 5) +
((sum(value&64)>0) << 6) +
((sum(value&128)>0) << 7) 
from numbers;


Sunday, January 8, 2012

Choose conferences with nice locations (Being Grad Students)

One of the nicest being a grad student is you get to travel, often "for free", to conference held at great places (e.g., Sydney, Paris, Hong Kong, etc.).

Picking such a conference could motivate you to work hard for a paper. :-) So choose your conference wisely. After all. If you have some good work that you can submit to similar conferences that have comparable reputation/prestige, which conference would you send it to? The nicer one of course.

Just remember to check with you advisor that it's OK with him/her though.

Cut your own hair (Being Grad Students)

When I was little, my father cut my hair. Then I came to the states for grad school -- no one cut my hair anymore!

Going to a hair salon in the US can be so expensive. The costs add up really quickly. So I thought about doing it myself; I remembered my father saying "it's a piece of cake" cutting my hair. How bad could it be if I did it myself?

Very bad, when I first started, a few years back. I bought a cheap Wahl hair clipper (like this one),  and I hated it, even though it's a 5 star product.
1) It has a long cord, which often get in the way
2) It's really awkward holding it to cut the side or the back of my head -- just try using your right hand to scratch your left ear from behind your head, and you'll know what I mean.
3) It's a big hassle having to keep changing the "length guides" for different hair lengths.

Apparently, you need something different when you cut your own hair. I found this Philips hair clipper recently, which solved all the above problems!!
1) It's cordless.
2) It has a rotating head, so you can hold it sideway when you cut your hair on the side or the back of your head
3) It has a "zoom ring" that lets you change the cutting length from 30mm (about 1.18 in) down to super close shave. No need to fiddle with the millions of "length guides"! (Well, technically, there are still two guides, one for the longer lengths, one for shorter lengths.)

I love this clipper. Great for a quick fix.

For those of you (men) who haven't cut your own hair before. It's very easy (assuming you use this Philips clipper, and you just want to style your hair a little). Here's how:

1a) Pick the longest length you want your hair to be (e.g., 30mm), and run the clipper through your whole head.
1b) If you want to style the top part of your hair (e.g., for parting, or styling), leave that part longer (or don't cut that at all) for later.
2) Pick a shorter one (e.g., 25cm) and run it along the areas close to the ear, and the back of your neck.
3) Repeat step 2, with even shorter length if desired. The key is to "blend" different lengths of hairs.
4) To add "layers" to your hair (to make your hair more "choppy" and to fine tune it to frame your face), use a pair of scissors, and cut "into" your hair like this.

Of course, if you need a really clean cut, or fancy style, you'll have to go to a hair salon.

Monday, May 25, 2009

Using BitSet or BitVector to store a set of integers

When programming with Java, we typically use HashSet to store a set of Integer, if we want to keep track of which Integer has been used and which hasn't. When we need to store millions of Integers, HashSet can be too slow, and it may take up too much memory.

Java's BitSet and BitVector from COLT are great alternative; they are MUCH faster and consumes way less memory. For example, to store 20 million integers, both BitSet and BitVector only use about 2.5MB and take only, respectively, 0.67s and 0.27s (which means BitVector is the fastest) to set and get all of the values once. using HashSet, it takes ~962MB, and 6.3s. This is more than 380 times of memory saving, and ~20 times speed up.

One "disadvantage" for BitVector is that it's size can't dynamically scale, but you can always fake it by manually growing or shrinking the set via setSize(...)

I can't figure out why Java's HashSet implementation uses so much RAM; I tried to reduce the size to 2 million, and that uses 100MB, approximately 1/10 of the size when having 20 millions. So this means indeed the Java implementation is memory-hungry. I'm sure there's some way to cut down the memory consumption, but I haven't spent the time to investigate.

Sunday, May 10, 2009

Speed Comparison of: (1) Java's built-in HashMap, (2) Trove's TIntIntHashMap, and (3) Colt's OpenIntIntHashMap

Finally get to do a comparison among several popular Java HashMap implementations:
  • Java's built-in HashMap
  • Trove's implementation for primitive types
  • Colt's implementation for primitive types
Not too surprisingly, Java's built-in implementation is the slowest, and consumes the largest amount of memory among the three, since it stores objects instead of primitive types (e.g., instead of storing the number 3 as an int, it stores it as an Integer). What WAS surprisingly, however, was that Colt's implementation was SO MUCH faster than Java's implementation. For example, for a int->int hashmap, running 10,000,000 puts() with Colt took less than 1/3 of the time. Running 10,000,000 gets() took less than 1/6, and 10,000,000 containsKey() less than 1/5! This is some substantial timing saving. This time-saving advantage is still there, even when we use a int->float[] hashmap. Memory-wise, the primitive implementations from Trove and Colt don't save us that much. For int->int hashmap, both Trove and Colt save us about 30% of memory, but for int->float[] (each float[] value has length 5) save us less than 10%. Nevertheless, there's still some saving. Since I need to deal with large data sets, where it's common to use hashmaps with millions of entries, I'll use the Colt implementation from now on, for both it's impressive time saving and (slighly) lower memory consumption. Here's the code I used for evaluating int->float[] hashmap. To get the timing and memory consumption for one implementation, comment out the other two that you DON'T want. You will also need to pass in these arguments to the VM, so enough heap memory will be alocated "-Xms1200M -Xmx1200M".
import java.util.HashMap;

import cern.colt.map.OpenIntIntHashMap;
import cern.colt.map.OpenIntObjectHashMap;
import gnu.trove.TIntIntHashMap;
import gnu.trove.TIntObjectHashMap;


public class Compare {
 
 public static void main(String args[]){
  
  System.out.println("1st line: time used(s)\n2nd line: heap memory used so far(MB)");
  
  int n = 10000000;
  
  long startTime = System.nanoTime(); 
  long startHeapSize = Runtime.getRuntime().freeMemory();

  
  // BEGIN: benchmark for Java's built-in hashmap
  System.out.println("\n===== Java's built-in HashMap =====");
  HashMap jIntIntMap = new HashMap();

  System.out.println("\n-- " + n + " puts(key, value) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { jIntIntMap.put(i,new float[]{0f,1f,2f,3f,4f}); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  
  System.out.println("\n-- " + n + " gets(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { jIntIntMap.get(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  

  System.out.println("\n-- " + n + " containsKey(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { jIntIntMap.containsKey(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  // END  
  
  
  // BEGIN: benchmark for Trove's TIntIntHashMap
  System.out.println("\n===== Trove's TIntIntHashMap =====");
  TIntObjectHashMap tIntIntMap = new TIntObjectHashMap();

  System.out.println("\n-- " + n + " puts(key, value) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { tIntIntMap.put(i,new float[]{0f,1f,2f,3f,4f}); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  
  System.out.println("\n-- " + n + " gets(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { tIntIntMap.get(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  

  System.out.println("\n-- " + n + " containsKey(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { tIntIntMap.containsKey(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  // END     
  
  // BEGIN: benchmark for Colt's OpenIntIntHashMap
  System.out.println("\n===== Colt's OpenIntIntHashMap =====");
  OpenIntObjectHashMap cIntIntMap = new OpenIntObjectHashMap();

  System.out.println("\n-- " + n + " puts(key, value) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { cIntIntMap.put(i,new float[]{0f,1f,2f,3f,4f}); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  
  System.out.println("\n-- " + n + " gets(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { cIntIntMap.get(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  

  System.out.println("\n-- " + n + " containsKey(key) --");
  startTime = System.nanoTime(); 
  for (int i = 0; i < n; i++) { cIntIntMap.containsKey(i); }
  System.out.println( (System.nanoTime() - startTime) / 1000000000.0 );
  System.out.println( (startHeapSize - Runtime.getRuntime().freeMemory()) /1048576.0  );  
  // END    
  
  
 }

}

Wednesday, December 3, 2008

Embedding web browser in Java application

I found this NativeSwing library an excellent library for embedding a web browser in a Java application, seemingly easier to use and much better documented that JDIC.

Thursday, June 28, 2007

WPF: getting a data-bound data template and the items within it

I'm so happy to find out about Rich Strahl's post on how to get the items within a data template that is data-bound to, say, a list box. It turns out the only way to get an item inside a data template is to programmatically go into the UI hierarchy of the template... not elegant at all!

Wednesday, June 27, 2007

The best tutorial about data binding in WPF

It turns out that Microsoft's MSDN has the best tutorial around about how to do data binding in WPF. Everything is explained clearly; the diagrams, tables, and examples are just perfect. Double thumbs up. Waaaay better than many other online data binding tutorials.

Saturday, June 16, 2007

The correct way to repaint a form or control in c#

There are two ways to repaint a form and its contents:

The Invalidate method governs what gets painted or repainted. The Update method governs when the painting or repainting occurs. If you use the Invalidate and Update methods together rather than calling Refresh, what gets repainted depends on which overload of Invalidate you use. The Update method just forces the control to be painted immediately, but the Invalidate method governs what gets painted when you call the Update method.

(Above info quoted from MSDN http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.update.aspx)