原来还通过路由器刷openwrt然后刷一堆东西抓包,现在不用了,用win7自带的wifi热点吧
代码如下:
1 2 |
netsh wlan set hostednetwork mode=allow ssid=bianbian-test key=bianbian.org netsh wlan start hostednetwork mode=allow |
原来还通过路由器刷openwrt然后刷一堆东西抓包,现在不用了,用win7自带的wifi热点吧
代码如下:
1 2 |
netsh wlan set hostednetwork mode=allow ssid=bianbian-test key=bianbian.org netsh wlan start hostednetwork mode=allow |
上月信用卡莫名刷出了美金,还百撕不得骑姐呢。。。
看了账单才知道是Amazon的aws ec2主机扣了我的费用,才知道原来ec2的免费策略是有各种各样限额的。
包括流量、IO。。。
一般是不会超的,不过要是也像我这种情况,被垃圾评论攻占的话。。。
ec的免费IO是一个月2百万次,但是怎么算IO呢,嗯,open一次算一次。
我给你解释一下一条垃圾评论大概会占用几次IO:
众所周知php为进程退出就清空所有上下文模式,所以一个访问:
看你include了多少php文件,就有几次IO,插件判断是垃圾评论吧,访问数据库吧,web日志,。。。
现在不得不开启注册用户才能发表评论模式了,然后注册表单里用了google的reCAPTCHA,先看看顶不顶得住。
附图一张:
其实我在此之前还写了个脚本自动添加Spam的ip到iptables的禁封列表里,结果发现太长了这个列表,会搞得服务器卡的一笔。贴在这里看需要的朋友吧:
1 2 3 4 5 |
$ cat makebanip.sh wget http://www.stopforumspam.com/downloads/bannedips.zip unzip bannedips.zip php makebanip.php chmod +x banip.sh |
1 2 3 4 5 6 7 8 9 10 11 12 |
$ cat makebanip.php <?php $ips = explode(',', file_get_contents('bannedips.csv')); $fp = fopen('banip.sh', 'w'); fwrite($fp, "iptables -F\n"); foreach ($ips as $ip) { if (strlen($ip) > 7) { fwrite($fp, "iptables -A INPUT -j DROP -s $ip\n"); } } fclose($fp); |
另外这个主题的作者是根据Akismet的spam清单里的ip地址来过滤的(不过他放到了nginx的deny ip里,其实也可以,不过iptables可能更前端一些)
chrome的所有用户data目录:
C:\Users\bianbian\AppData\Local\Google\Chrome\User Data\Default
上面bianbian替换成你的用户名
因为我的R:盘是内存盘,所以把几个cache目录全指过去:
1 2 3 4 |
rmdir "C:\Users\bianbian\AppData\Local\Google\Chrome\User Data\Default\Cache" rmdir "C:\Users\bianbian\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash" mklink /D "C:\Users\bianbian\AppData\Local\Google\Chrome\User Data\Default\Cache" "R:\Internet 临时文件" mklink /D "C:\Users\bianbian\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash" "R:\Internet 临时文件" |
好吧,记不清什么原因了,似乎是用apt-get remove mysql-server卸掉了mysql,然后手动删除了部分mysql的配置文件(好吧,先鄙视自己不用apt-get purge)
不过后来又要用到,于是再install,这时候死活装不上。
基本错误是这样,提示install成功了,不过起不来:
service mysql start start: Rejected send message
然后用apt-get remove mysql-server mysql-client,就install不了了:
1 2 3 4 |
apt-get install mysql-server mysql-client: ... invoke-rc.d: unknown initscript, /etc/init.d/mysql not found ... |
好吧,它提示/etc/init.d/mysql找不到,后来搜了一下,假装给他一个:
1 2 3 4 |
vi /etc/init.d/mysql 内容: #!/bin/true chmod 755 /etc/init.d/mysql |
再次 apt-get remove –purge mysql-server mysql-client
总算清掉了,再一次安装成功:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
root@localhost:~# apt-get install mysql-server Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libgsasl7 guile-1.8-libs libntlm0 Use 'apt-get autoremove' to remove them. The following extra packages will be installed: mysql-server-5.5 Suggested packages: tinyca mailx The following NEW packages will be installed: mysql-server mysql-server-5.5 0 upgraded, 2 newly installed, 0 to remove and 3 not upgraded. Need to get 8,840 kB/8,852 kB of archives. After this operation, 32.8 MB of additional disk space will be used. Do you want to continue [Y/n]? y Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu/ precise-updates/main mysql-server-5.5 amd64 5.5.37-0ubuntu0.12.04.1 [8,840 kB] Fetched 8,840 kB in 1s (8,782 kB/s) Preconfiguring packages ... Selecting previously unselected package mysql-server-5.5. (Reading database ... 80928 files and directories currently installed.) Unpacking mysql-server-5.5 (from .../mysql-server-5.5_5.5.37-0ubuntu0.12.04.1_amd64.deb) ... Selecting previously unselected package mysql-server. Unpacking mysql-server (from .../mysql-server_5.5.37-0ubuntu0.12.04.1_all.deb) ... Processing triggers for ureadahead ... Processing triggers for man-db ... Setting up mysql-server-5.5 (5.5.37-0ubuntu0.12.04.1) ... 140606 9:25:05 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead. mysql start/running, process 25510 Setting up mysql-server (5.5.37-0ubuntu0.12.04.1) ... |
IDL默认方式的数字是短整型(16-bit int)。所以如下的声明方式其实是报错的:
1 2 3 4 |
arr = IntArr(1024 * 32) % Array dimensions must be greater than 0. % Execution halted at: $MAIN$ |
因为,1024*32=32768,超过了短整型上限(32767),从二进制码基础可知会跳到该类型的另一头,即:
1 2 |
IDL> print, 1024*32 -32768 |
这时有两种解决办法,一种显示声明为Long(32-bit int),即数字后面跟上L:
1 |
arr = IntArr(1024L * 32) |
另外一种事先声明:
1 |
compile_opt idl2 |
idl2参见文档,记得是编译开关:1)把所有数字作为Long型 2)用中括号表示数组下标,即[]
http://www.exelisvis.com/docs/COMPILE_OPT.html
好吧。本来想多写点的,现在没时间,太监了。
说下核心:客户端自定义的http header,在nginx的配置文件里能直接读取到。
条件:header必须用减号“-”分隔单词,nginx里面会转换为对应的下划线“_”连接的小写单词。
nginx配置:
1 2 3 4 5 |
location / { if ($http_my_custom_header ~ (\d+) ) { rewrite / http://google.com/ last; } } |
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
wget --header="my-custom-header:1" -d https://blog.bbdd.ltd DEBUG output created by Wget 1.13.4 on linux-gnu. URI encoding = `UTF-8' --2014-04-28 09:48:40-- https://blog.bbdd.ltd/ Resolving bianbian.org (bianbian.org)... 172.31.30.70 Caching bianbian.org => 172.31.30.70 Connecting to bianbian.org (bianbian.org)|172.31.30.70|:80... connected. Created socket 3. Releasing 0x084e3e18 (new refcount 1). ---request begin--- GET / HTTP/1.1 User-Agent: Wget/1.13.4 (linux-gnu) Accept: */* Host: bianbian.org Connection: Keep-Alive my-custom-header: 1 ---request end--- HTTP request sent, awaiting response... ---response begin--- HTTP/1.1 302 Moved Temporarily Server: nginx/1.1.19 Date: Mon, 28 Apr 2014 09:48:40 GMT Content-Type: text/html Content-Length: 161 Connection: keep-alive Location: http://google.com |
好吧,又一次被IDL坑了。怪我自己没看仔细,主要语言太多。。。
比如:
C系列的逻辑判断符是 && || !
Delphi的逻辑判断符是AND OR NOT
写在这里,起警示作用:
IDL的逻辑判断符是这样的:&& || ~
IDL的位操作符是这样的:AND OR NOT XOR
以前写判断都是 if … and … then …
所以从来没注意and原来是(Bitwise AND),not原来是(Bitwise NOT)
好吧,因为以前的判断基本都是逻辑组合(即 if ID gt 2 and ID lt 5 then…)为主,所以基本两个的结果是一样的,没出过问题。
坑来了:
id = -2
if not id then …
(not -2) equals 1
所以,以后IDL逻辑判断全部要用 && || ~
Nagios® Core™ is an Open Source system and network monitoring application. It watches hosts and services that you specify, alerting you when things go bad and when they get better.Nagios Core was originally designed to run under Linux, although it should work under most other unices as well.
以下是2014-4-17安装记录:
== 服务端 ==
安装依赖包:(其实不装也能安装成功,就是部分功能会disabled)
1 2 |
sudo apt-get install build-essential libssl-dev \ libgd2-xpm-dev libpng12-dev php5-gd libgd2-xpm |
用户组:
1 2 3 4 |
sudo adduser --system --no-create-home --disabled-login --group nagios sudo groupadd nagcmd sudo usermod -G nagcmd nagios sudo usermod -a -G nagcmd www-data |
从 http://www.nagios.org/download/ 下载解压:
1 2 3 4 5 6 7 |
cd /tmp mkdir nagios cd nagios wget http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-4.0.5.tar.gz wget http://www.nagios-plugins.org/download/nagios-plugins-2.0.1.tar.gz tar zxf nagios-4.0.5.tar.gz tar zxf nagios-plugins-2.0.1.tar.gz |
编译安装:
1 2 3 4 5 6 7 8 9 |
cd /tmp/nagios/nagios-4.0.5 ./configure --prefix=/opt/nagios --sysconfdir=/etc/nagios \ --with-nagios-user=nagios --with-nagios-group=nagios \ --with-command-user=nagios --with-command-group=nagcmd make all sudo make install sudo make install-init sudo make install-config sudo make install-commandmode |
建立htpasswd.users,这个如果装了apache2有htpasswd这个命令,不然可以用某个python脚本:
(如果服务器不想装python,可以找台有python的服务器;或者找台装了apache的机器运行htpasswd;或者装个httpd不启动也没关系)
(生成的htpasswd.users是个文本文件,复制到服务器的 /etc/nagios/htpasswd.users)
1 2 3 |
wget http://trac.edgewall.org/export/10791/trunk/contrib/htpasswd.py chmod +x htpasswd.py ./htpasswd.py -c -b /etc/nagios/htpasswd.users nagiosadmin "password" |
修改联系人email,在contacts.cfg的email那里(34行)
1 |
sudo vi /etc/nagios/objects/contacts.cfg |
安装mail报警通知所需包(安装时选择”Internet Site”;输入域名)
(注意:不装这个mail包编译nagios-plugins-2.0.1会error,但是编译nagios-plugins-2.0没问题。。。)
1 2 |
sudo apt-get install mailutils postfix sudo ln -s /usr/bin/mail /bin/mail |
安装插件:
1 2 3 4 5 |
cd /tmp/nagios/nagios-plugins-2.0.1 ./configure --prefix=/opt/nagios --with-nagios-user=nagios --with-nagios-group=nagios make sudo make install sudo chown -R nagios:nagios /opt/nagios |
启动nagios
1 2 |
sudo ln -s /etc/init.d/nagios /etc/rcS.d/S99nagios sudo service nagios start |
安装fcgi
1 |
sudo apt-get install spawn-fcgi fcgiwrap |
编辑nginx.conf
1 |
sudo vi /etc/nginx/sites-enabled/nagios |
其中对/nagios/开头的地址进行了rewrite,(nagios内部很多页面是写死/nagios/开头的,导致images、css等出不来)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
server { server_name nagios.bianbian.org; access_log /var/log/nginx/nagios.access.log; error_log /var/log/nginx/nagios.error.log; auth_basic "Restricted Nagios Area!"; auth_basic_user_file /etc/nagios/htpasswd.users; root /opt/nagios/share/; location ~ ^/nagios/ { rewrite ^/nagios/(.*) /$1 permanent; } location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.socket; } location ~ \.cgi$ { root /opt/nagios/sbin/; rewrite ^/cgi-bin/(.*)\.cgi /$1.cgi break; fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; include fastcgi_params; fastcgi_pass unix:/var/run/fcgiwrap.socket; } } |
启动服务
1 |
sudo service nagios start |
登录后就看到nagios的监控界面了
OpenSSL can safely be used in multi-threaded applications provided that at least two callback functions are set, locking_function and threadid_func.
OpenSSL 是线程安全的,前提是必须注册两个回调函数。其中根据 Openssl 的版本不同,会有不同 版本的 threadid 回调函数。
如果不注册回调函数,多线程下压力一大必挂无疑。基本都是core dump:
libcrypto.so
下面贴主要代码,如何注册使用这两个回调函数:
.h
1 2 3 4 5 6 7 8 9 10 |
//声明 #ifndef OPENSSL_VERSION_1_0_0 #define OPENSSL_VERSION_1_0_0 0x10000000L #endif #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 void ssl_threadid_function_callback(CRYPTO_THREADID* id); #else unsigned long ssl_threadid_function_callback_deprecated(); #endif void ssl_lock_callback(int mode, int type, char *file, int line); |
.c
我这里用的是libuv,所以代码里是uv_mutex_t*,如果是pthreads,就换成 pthread_mutex_t*;相应的 uv_thread_self() 换成 pthread_self()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
//存lock的 static uv_mutex_t* ssl_locks; //初始化 ssl_locks = calloc(CRYPTO_num_locks(), sizeof(uv_mutex_t)); for (int i=0; i< CRYPTO_num_locks(); i++) { uv_mutex_init(&(ssl_locks[i])); } #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 CRYPTO_THREADID_set_callback(ssl_threadid_function_callback); #else CRYPTO_set_id_callback(ssl_threadid_function_callback_deprecated); #endif CRYPTO_set_locking_callback(ssl_lock_callback); //销毁 #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 CRYPTO_THREADID_set_callback(NULL); #else CRYPTO_set_id_callback(NULL); #endif CRYPTO_set_locking_callback(NULL); for (int i=0; i < CRYPTO_num_locks(); i++) { uv_mutex_destroy(&(ssl_locks[i])); } free(ssl_locks); //回调函数 #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 void ssl_threadid_function_callback(CRYPTO_THREADID* id) { CRYPTO_THREADID_set_numeric(id, (unsigned long)uv_thread_self()); } #else unsigned long ssl_threadid_function_callback_deprecated() { return (unsigned long)uv_thread_self(); } #endif void ssl_lock_callback(int mode, int type, char *file, int line) { if (mode & CRYPTO_LOCK) { uv_mutex_lock(&(ssl_locks[type])); LOGT("ssl locked: [type] %d, [file] %s, [line] %d", type, file, line); } else { uv_mutex_unlock(&(ssl_locks[type])); LOGT("ssl unlock: [type] %d, [file] %s, [line] %d", type, file, line); } } |
打开Trace日志,果然一堆lock的坑啊。。。。
…
… ssl locked: [type] 16, [file] ssl_lib.c, [line] 512
… ssl unlock: [type] 16, [file] ssl_lib.c, [line] 512
… ssl locked: [type] 2, [file] ex_data.c, [line] 304
… ssl unlock: [type] 2, [file] ex_data.c, [line] 325
… ssl locked: [type] 2, [file] ex_data.c, [line] 500
… ssl unlock: [type] 2, [file] ex_data.c, [line] 511
…
简单看了下OpenSSL的基本算法源码,可能OpenSSL当年实现的时候内存比较精贵,所以很多算法都是static的内存块,不停new free内存,所以多线程下必须用各种lock。
内存如此便宜的现如今,这种实现方法显然不符合多线程、高并发的潮流了。。。
参考:
http://www.openssl.org/docs/crypto/threads.html
http://blog.csdn.net/yasi_xi/article/details/19125103
1)./fullinstall会报各种包依赖错误。(其实是 ./1-prereqs 这一步)
需要先卸载原来的mysql、php,反正哪些包依赖错误就卸掉原来的。
2)Nagios默认的httpd是apache,所以默认安装各种出错。修改 ./xi-sys.cfg
把 httpd='httpd'改成 httpd='nginx'
3)./A-subcomponents
Nagios的subcomponents里面很多install / post-install脚本还是写死的
service httpd restart,要改成 service $httpd restart
(nagioscore、nrdp),nagiosmobile是php写的安装脚本,不改没关系(不影响结果,不过会执行不下去)
反正按subcomponents的install脚本照着来,如果每个都确认解压或者复制成功,不用重头执行A-subcomponents,
直接 touch installed.subcomponents 算了
4)./B-installxi
跟上面3)的问题一样,httpd 改成 $httpd
5)./E-importnagiosql
因为apache的conf和nginx完全不同(而前面步骤Nagios装的是apache的conf),这一步需要访问
http://localhost/nagiosql/index.php 肯定出错,导致这一步出问题。
在/etc/nginx/nginx.conf内新增一行:
include /etc/nginx/conf.d/nagiosxi.conf;
在/etc/nginx/conf.d/下新建nagiosxi.conf,参照/etc/httpd/conf.d/nagiosql.conf设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
server { listen 80; server_name localhost; location /nagiosql { root /var/www/html/nagiosql; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } |
(待续)
.NET Native compiles C# to native machine code that performs like C++. You will continue to benefit from the productivity and familiarity of the .NET Framework with the great performance of native code. Popular Windows Store apps start up to 60% faster and use 15-20% less memory when compiled with .NET Native.
链接在此:Microsoft .NET Native
netty支持linux的epoll是4.0.17.Final引入的新功能,不过测试使用发现几个bug。暂记如下:
[已解决的]
使用epoll时channel关闭错误
1 2 |
java.nio.channels.ClosedChannelException: null at io.netty.channel.epoll.Native.readAddress(Native Method) |
原因:Native.finishConnect()中有bug
见这里:https://github.com/netty/netty/issues/2280
下载最新代码编译package可解决。包括编译Native的c代码:
1 |
gcc -fPIC -shared -o libnetty-transport-native-epoll.so -I/jdk/include/ io_netty_channel_epoll_Native.c |
[未解决的]
使用epoll时channel中取不到localAddress()和remoteAddress()
1 2 3 4 |
Channel channel = channelHandlerContext.channel(); log.warn("channel {} isActive {}", channel, channel.isActive()); log.warn("localAddress {}", channel.localAddress()); log.warn("remoteAddress {}", channel.remoteAddress()); |
log:
1 2 3 |
18:10:27.076 176719 [nioEventLoopGroup-5-1] WARN c.v.b.c.ClientChannelNetty4Impl [118] - channel [id: 0x892e0c3c] isActive true 18:10:27.077 176720 [nioEventLoopGroup-5-1] WARN c.v.b.c.ClientChannelNetty4Impl [119] - localAddress null 18:10:27.077 176720 [nioEventLoopGroup-5-1] WARN c.v.b.c.ClientChannelNetty4Impl [120] - remoteAddress null |
github上有相关的issue: https://github.com/netty/netty/issues/2262
虽然标记为已解决,但编译4.0最新的代码(4.0.18.Final-SNAPSHOT)错误仍在。
先记录下,明天再来看怎么回事。
家里宽带是电信的100M光纤。不过有时候会莫名其妙断线,而且只能通过重启路由器来解决。(10000反映多次未果。。。)
于是没办法,写了个nodejs脚本(这是我第一个nodejs程序好吗)来判断是否断线并重启路由器。
本文所用路由器型号为Netgear 6300 v2
主要思路:
检查 http://10.0.0.1/ADV_home2.htm
根据内容里的:Domain Name Server 是否存在有效的DNS来判断是否断线
如果断线,则提交相应的数据(buttonSelect=2)使Netgear路由器重启
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
/* 若Netgear 6300 v2网络断线,重启路由。 https://blog.bbdd.ltd */ var http = require('http'); var qs = require('querystring'); function substrAfter(s, subs, length){ return s.substr(s.indexOf(subs) + subs.length, length); } function checkRestart(){ var options = { hostname: '10.0.0.1', path: '/ADV_home2.htm', auth: 'admin:password' }; console.log('check...' + new Date()); var req = http.request(options, function (res){ var _s = ''; res.on('data', function (chunk){ _s += chunk; }); res.on('end', function() { var s = substrAfter(_s, '<form action="newgui_adv_home.cgi?id=', 10000); if (s.match(/^(\d+)/)) { var sid = RegExp.$1; _s = substrAfter(s, '>Domain Name Server', 300); if (_s.match(/>(\d{1,3}\.){3}\d{1,3}</) && RegExp.$1 != '0.') { console.log('ok'); } else { console.log(_s); restart(sid); } } }); }).on('error', function(e) { console.log('****error: ' + e.message); }); req.end(); }; function restart(sid){ var data = {buttonSelect:2, wantype:'pppoe', enable_apmode:0}; var query = qs.stringify(data); var options = { hostname: '10.0.0.1', path: 'newgui_adv_home.cgi?id=' + sid, method: 'POST', auth: 'admin:password', headers:{ 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': query.length } }; console.log('restart...'); var req = http.request(options, function(res) { res.on('data', function (chunk) { ; }); }).on('error', function(e) { console.log('****error: ' + e.message); }); req.write(query); req.end(); } checkRestart(); setInterval(checkRestart, 60000); |
这个需求一般是查询一个look-up-table,比如数据定标表,假设有如下一个数组(实际数组比这大很多,只是为了举例):
现在要找 1.5 最接近的数值:
1 2 3 4 |
IDL> arr = Randomu(1, 10) * 10 IDL> print, arr 4.17022 9.97185 7.20325 9.32557 0.00114381 1.28124 3.02333 9.99041 1.46756 2.36089 |
我一开始用的是先把数组sort,然后用二分法查找(代码不贴了,很简单)
后来一想IDL应该有内置支持这种查找吧,发现有 Value_Locate 方法,可以解决问题。
但是缺点很明显,需要先sort
后来找到这里:Locating a Value in an Array
我稍微改进了一下,因为Min支持 /ABSOLUTE 参数:
1 2 3 4 |
IDL> value = 1.5 IDL> near = Min(arr - value, idx, /ABSOLUTE) IDL> print, idx, arr[idx], near 8 1.46756 -0.0324411 |
适合所有IDL使用者好好看看:
Tips & Tricks for Efficient IDL Programming
尤其是3、5、9、10条:
3、Try to avoid IF statements within loops. When an IF statement appears in the middle of a loop with each element of an array in a conditional, the loop can be eliminated most of the time by using logical array expressions.
Slow:
for i = 0L, n_elements(data)-1L do $
if (data[i] le 30) then $
data[i] = 30
Faster:
dex = where(data le 30, count)
if (count gt 0) then data[dex] = 30
Even faster:
data = ((data gt 30) * data) + ((data le 30) * 30)
Fastest:
data = data > 30
5、Access large arrays by memory order. Arrays in IDL are column-major order. The important thing to remember is that IDL indexes arrays as [column, row]. The upper left-hand element of a matrix is considered to be [0,0]. This is the format used by FORTRAN, and is traditionally associated with image processing because it keeps all the elements of a single image scanline together. In contrast C and Visual Basic use row-major order and indexes its data as [row,column].
When an array is larger than or close to the working set size (the amount of physical memory available for the process) it should be accessed in memory order, meaning access it by accessing rows first.
for x = 0, 511 do for y = 0, 511 do arr[x, y] = ….
is very inefficient because to read the first column 250,000 bytes of data must be read into physical memory. This process must be repeated for each column, requiring the entire array to be read and written almost 512 times. By exchanging the two FOR loops the computing time can be reduced by a factor of 50:
for y = 0, 511 do for x = 0, 511 do arr[x, y] = ….
9. Use of the TEMPORARY function minimizes memory use when performing operations on large arrays. TEMPORARY reassigns to a new variable the memory referred to by its argument, deleting the old variable reference in the process (though the reassignment may be to a variable that reuses the original name). Assume that A is a large array. To add 1 to each element of A this is one coding option:
A = A + l
This statement creates a new array for the result of the addition and assigns the result to A before freeing the old allocation of A. Therefore, this operation needs 2*sizeof(A) of memory to perform the operation. The statement
A = temporary(A) + 1
needs no additional space.
10. Try not to use “*” for array indexing on the left hand side of a statement. Instead, use “0.” For instance, for the array
B = intarr(200, 200, 3)
it is much slower to use the following notation
B[*,*,1] = insertData
than to use
B[0,0,1] = insertData
The first notation is inefficient because the IDL interpreter will allocate/build a 200 x 200 long integer array of subscript indexes to substitute for the wildcard token. The latter notation does not need an array of subscripts; it performs direct copy to memory. (Note that ‘insertData’ must fit in the 200 x 200 x 2 memory space that defines the borders of the subarray that starts at ‘B[0,0,1]’ in order to avoid an array-out-of-bounds error.)