Monday, October 27, 2008

Perl - Implementing a Sparse Array

Perl -Implementing a Sparse Array

4.4.1 Problem

An array with large, unoccupied expanses between occupied elements wastes memory. How do you reduce that overhead?

4.4.2 Solution

Use a hash instead of an array.

4.4.3 Discussion

If you assign to the millionth element of an array, Perl allocates a million and one slots to store scalars. Only the last element contains interesting data, leaving earlier ones each set to undef at a cost of four (or more) bytes per unoccupied slot.

In recent versions of Perl, if you grow an array by assigning either past the end or directly to $#ARRAY, you can distinguish these implicit undefs from those that would result from assigning undef there by using exists instead of defined, just as you would with a hash.

$#foo = 5;
@bar = ( (undef) x 5 ) ;

printf "foo element 3 is%s defined\n",
defined $foo[3] ? "" : "n't";
printf "foo element 3 does%s exist\n",
exists $foo[3] ? "" : "n't";
printf "bar element 3 is%s defined\n",
defined $bar[3] ? "" : "n't";
printf "bar element 3 does%s exist\n",
exists $bar[3] ? "" : "n't";

foo element 3 isn't defined
foo element 3 doesn't exist
bar element 3 isn't defined
bar element 3 does exist

However, you still waste a lot of space. That's because Perl's array implementation reserves a contiguous vector, one for each element up to the highest occupied position.

$real_array[ 1_000_000 ] = 1;       # costs 4+ megabytes

A hash works differently: you pay only for what you really use, not for unoccupied positions. Although a hash element costs somewhat more than an array element because you need to store both the value and its key, with sparse arrays, the savings can be astonishing.

$fake_array{ 1_000_000 } = 1;       # costs 28 bytes

What's the trade-off? Because a hash's keys aren't ordered, a little more work is needed to sort the numeric keys so you can handle their values in the same order as you would if they were stored as a real array. With an array, you'd just do this to process elements in index order:

foreach $element ( @real_array ) {
# do something with $element
}

or this to process indices in ascending order:

foreach $idx ( 0 .. $#real_array ) {
# do something with $real_array[$idx]
}

Using a hash representation, you should instead do either this to process elements in index order:

foreach $element ( @fake_array{ sort {$a <=> $b} keys %fake_array } ) {
# do something with $element
}

or this to process indices in ascending order:

foreach $idx ( sort {$a <=> $b} keys %fake_array ) {
# do something with $fake_array{$idx}
}

If you don't care about handling elements in a particular order, however, you don't need to go through all that. Just process the values according to their internal order, either like this:

foreach $element ( values %fake_array ) {
# do something with $element
}

or like this:

# process indices in internal hash order
foreach $idx ( keys %fake_array ) {
# do something with $fake_array{$idx}
}

If you're determined to use an array, two fairly specialized cases occasionally arise in which you can save substantial amounts of memory by using an alternate storage scheme. Both cases also apply to arrays that are densely populated, not just those that are mostly empty.

The first case shows up when you grow an array by repeatedly appending new elements until its subscripts become large. Because of how Perl reallocates memory for growing arrays, this can use up to four times the memory you really need. If you happen to know how big the array will (or might) eventually become, you can avoid this reallocation overhead either by storing the large subscripts first instead of the small ones:

for ($i = 10_000; $i >= 0; $i--) { $real_array[$i] = 1 }

or by presizing the array by assigning to the special $#ARRAY notation:

$#real_array = 10_000;

The second special case comes up when each array element holds nothing but a single one-bit valueessentially either a true or a false. For example, suppose you are keeping track of numbered USENET news articles, and you only need to know whether a given article number has been read. For situations like this, use a bit vector instead of a real array:

my $have_read = '';

for ($i = 10_000; $i >= 0; $i--) { vec($have_read, $i, 1) = 1 }

Then you can check to see whether a given article has been read this way:

if (vec($have_read, $artno, 1)) { .... }

4.4.4 See Also

The vec function in perlfunc(1) and in Chapter 29 of Programming Perl

Friday, October 10, 2008

笔记本常识之:LCD、LED与OLED的区别

笔记本常识之:LCD、LED与OLED的区别

  笔记本液晶屏(LCD, Liquid crystal display)常用的是TFT。TFT屏幕是薄膜晶体管,英文全称(Thin Film Transistor),是有源矩阵类型液晶显示器,在其背部设置特殊光管,可以主动对屏幕上的各个独立的像素进行控制,这也是所谓的主动矩阵TFT的来历,这样可以大的提高么应时间,约为80毫秒,而STN的为200毫秒!也改善了STN闪烁(水波纹)模糊的现象,有效的提高了播放动态画面的能力,和STN相比,TFT有出色的色彩饱和度,还原能力和更高的对比度,太阳下依然看的非常清楚,但是缺点是比较耗电,而且成本也较高。

  LED是发光二极管Light Emitting Diode的英文缩写。

  LED应用可分为两大类:一是LED单管应用,包括背光源LED,红外线LED等;另外就是LED显示屏,目前,中国在LED基础材料制造方面与国际还存在着一定的差距,但就LED显示屏而言,中国的设计和生产技术水平基本与国际同步。

  LED显示屏是由发光二极管排列组成的一显示器件。它采用低电压扫描驱动,具有:耗电少、使用寿命长、成本低、亮度高、故障少、视角大、可视距离远等特点。

  LED显示器与LCD显示器相比,LED在亮度、功耗、可视角度和刷新速率等方面,都更具优势。LED与LCD的功耗比大约为10:1,而且更高的刷新速率使得LED在视频方面有更好的性能表现,能提供宽达160°的视角,可以显示各种文字、数字、彩色图像及动画信息,也可以播放电视、录像、VCD、 DVD等彩色视频信号,多幅显示屏还可以进行联网播出。有机LED显示屏的单个元素反应速度是LCD液晶屏的1000倍,在强光下也可以照看不误,并且适应零下40度的低温。利用LED技术,可以制造出比LCD更薄、更亮、更清晰的显示器,拥有广泛的应用前景。

  简单地说,LCD与LED是两种不同的显示技术,LCD是由液态晶体组成的显示屏,而LED则是由发光二极管组成的显示屏。LED显示器与LCD显示器相比,LED在亮度、功耗、可视角度和刷新速率等方面,都更具优势。

  OLED:Organic Light Emitting Display,即有机发光显示器,在手机LCD上属于新崛起的种类,被誉为“梦幻显示器”。OLED显示技术与传统的LCD显示方式不同,无需背光灯,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光。而且OLED显示屏幕可以做得更轻更薄,可视角度更大,并且能够显著节省电能。 不过,虽然将来技术更优秀的OLED会取代TFT等LCD,但有机发光显示技术还存在使用寿命短、屏幕大型化难等缺陷。

Wednesday, October 8, 2008

Linux log files location and how do I view logs files?

Linux log files location and how do I view logs files?

Go to /var/logs directory:
cd /var/logs

View common log file /var/log/messages using any one of the following command:
tail -f /var/log/messages
less /var/log/messages
more -f /var/log/messages
vi /var/log/messages