0%

Partion Application

顧名思義,提供函數一部分的參數。變成一個新的函數。
最簡單的例子就像這樣

1
2
3
4
5
6
7
8
int sub(int a, int b)
{
return a - b;
}
int sub2(int v)
{
return sub(v, 2);
}

當然上面這種寫法復用度並不高,於是在C++11把bind跟function納入標準配備之後,可以寫成這樣。

1
std::function<int(int)> sub2 = std::bind(sub, std::placeholders::_1, 2);

有時間再來討論bind跟function。
不過就可讀性來說,Pyhton版的強多了

1
2
3
4
5
import functools
def sub(a, b):
return a - b

sub_two = functools.partial(sub, b = 2)

Currying

Currying是為了解決不一樣的問題
假設一個函數有多個參數,把他轉化成多個只有一個參數的函數組合。
用C++11的Lambda Expression來做示範。

1
2
3
4
5
6
7
std::function<int(int)> add2(int a)
{
return std::function<int(int)>([=](int b) -> int{
return a + b;
});
}
cout << add2(3)(5) << endl;

基本上PCurrying可以實現一部分Partion Application的應用。不過以上麵的sub2為例,Currying在這邊就不是用。
更清楚的描述可以看What is the difference between currying and partial application

不知道哪時候會用到,先做個筆記。需要的話再跟巨觀建字去搜尋。

測試工具

不定期更新

C Language

C++ Language

未分類

Stackoverflow看到這串討論很有意思。
以下的Code,雖然時間複雜度都一樣O(n),不過排序過後的速度遠遠超過沒排序,將sort註解掉之後可以看出很明顯的差異。

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
#include <algorithm>
#include <ctime>
#include <iostream>

int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];

for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;

// !!! With this, the next loop runs faster
//std::sort(data, data + arraySize);

// Test
clock_t start = clock();
long long sum = 0;

for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c)
{
if (data[c] >= 128)
sum += data[c];
}
}

double elapsedTime = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;

std::cout << elapsedTime << std::endl;
std::cout << "sum = " << sum << std::endl;
}
Read more »

寫起來,免得忘記。

在程式Crash前直接呼叫gdb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void dump(int signo)
{
char buf[1024];
char cmd[1024];
FILE *fh;

snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid());
if (!(fh = fopen(buf, "r")))
exit(0);
if (!fgets(buf, sizeof(buf), fh))
exit(0);
fclose(fh);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
snprintf(cmd, sizeof(cmd), "gdb %s %d", buf, getpid());
system(cmd);

exit(0);
}
signal(SIGSEGV, &dump);
Read more »

對最近的心得做個總結。
這篇Boost application performance using asynchronous I/O描述了幾種常用的IO Model。
首先要先解釋兩個很像,卻又部太相同的名詞

  • Synchronous Application發起I/O Operation,並且等待其完成 (如 read / write)
  • Non-Synchronous Application僅發起I/O Program Request,由Kernel通知Application完成
  • Blocking Application因為等待某事件,而不能繼續往下執行
  • Non-Blocking Application不受事件影響

Synchronous blocking I/O

最常見的I/O Model,就是在Event未結束前不會將控制權交還給Application。

1
2
int len = recv(s, .....);
// Do other things

在這種Model之下,為了要解決Blocking的問題,就得使用Multi-Porcess或是Multi-Thread的方式來做。

Read more »

隨著Java8推出,新增了一堆新特性。其中有一項就是C# 3.0有的Extension Method。紀錄一下。

問題

在OOP的世界裡,一旦介面推出之後,就不能在更改了。否則依賴於這介面開發的程式必須更著改動。如果Source Code都在自己手上還好。如果是3rd party或是已不在維護的Library,這就變成問題。

1
2
3
4
5
6
7
8
9
public interface MyInterface {
void myFunc();
}
public class Obj1 implements MyInterface {
public void myFunc() {}
}
public class Obj2 implements MyInterface {
public void myFunc() {}
}

如果如果現在Interface需要增加一個myFunc2的功能,該怎麼作。

Read more »

Docker跟Virtual Box這種Virtual Machine上的虛擬化不同,他是基於64 bit linux上,由cgroups/AUFS/LXC為基礎發展出來的Linux virtualization,目前也僅能在Linux上跑,相對於VM等級,更輕量化且更省資源。

安裝

由於Docker需要Linux kernel 3.8以上的,如果版本比較舊的要先更新

1
2
$ sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
$ sudo shutdown -r now

Update: Ubuntu 14.04

由於Ubuntu 14.04直接收入Docker
所以直接安裝docker.io就好,然後以下的指令全部用docker.io取代docker

1
$ sudo apt-get install docker.io

將Docker的PGP Key跟Repository加入環境中

1
2
$ sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"
$ sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"

跟新Source且安裝LXC-Docker

1
2
$ sudo apt-get update
$ sudo apt-get install lxc-docker
Read more »

開始玩虛擬化之後,紀錄如何用VirtualBox + Vagrant打造自己的開發環境。

Box

可以把Box想像成光碟,需要安裝的時候,就拿出光碟開始安裝環境。

1
2
3
$ vagrant box list # 列出目前所有的Box
$ vagrant box add {title} {url}
$ vagrant box remove {title}

從網路下載的Box會存在`~.vagrant.d\boxes’下。

Create a virtual machine

有兩種方式,從Box衍生出來,或是寫個VagrantFile衍生。

從Box開始

1
2
$ vagrant init {title}
$ vagrant init {boxname}

後者會將box存到Box List中。
兩者都會產生一個VagrantFile檔案。

Read more »

看了這篇 C11 - Generic Selections
第一直覺感覺和C++ Template很像,不過也不太一樣。
這是C11的Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
void funci(int x)
{
printf("func value = %d\n", x);
}
void funcc(char c)
{
printf("func char = %c\n", c);
}
void funcdef(double v)
{
printf("Def func's value = %lf\n", v);
}
#define func(X) _Generic((X), int: funci, char: funcc, default: funcdef)(X)
int main()
{
func(1);
func('a');
func(1.3);
return 0;
}
Read more »