Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active December 3, 2017 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/2b26c0bf1c1f81b0f8827271d1cb900a to your computer and use it in GitHub Desktop.
Save tompng/2b26c0bf1c1f81b0f8827271d1cb900a to your computer and use it in GitHub Desktop.
#include <stdio.h>
int main(){
char bytes[65536];
int len;
int count = 0;
int col = 0;
int filter[256]={0};
for(int i=0;i<5;i++)filter["aeiou"[i]]=1;
while((len = fread(bytes, 1, 65536, stdin)) > 0){
for(int i=0; i<len; i++){
char b=bytes[i];
if(b=='\n'){
col=0;
}else if(b==','){
col++;
}else if(col==1){
count+=filter[b];
}
}
}
printf("%d\n", count);
return 0;
}
package main
import (
"fmt"
"os"
)
func main() {
var count, col int
buf := make([]byte, 65536)
arr := make([]int, 256)
for _, c := range "aeiou" {
arr[c] = 1
}
for {
len, err := os.Stdin.Read(buf)
if err != nil {
break
}
for i := 0; i < len; i++ {
c := buf[i]
if c == ',' {
col++
} else if c == '\n' {
col = 0
} else if col == 1 {
count += arr[c]
}
}
}
fmt.Println(count)
}
count = 0
target = 'aeiou'
s = ''
STDIN.each_line do |line|
s << line.split(',', 2).last
if s.size > 0x10000
count += s.count target
s = ''
end
end
puts count + s.count(target)
package main
import (
"fmt"
"os"
)
type Input struct {
id, len int
buf []byte
}
type TempResult struct {
id, first, second, count, col int
}
func partialCount(in Input, chBuf chan []byte, chResult chan TempResult) {
firstRow := true
var col int
var result TempResult
filter := make([]int, 256)
for _, c := range "aeiou" {
filter[c] = 1
}
for i := 0; i < in.len; i++ {
c := in.buf[i]
if c == ',' {
col++
} else if c == '\n' {
col = 0
firstRow = false
}
if firstRow {
if col == 0 {
result.first += filter[c]
} else if col == 1 {
result.second += filter[c]
}
} else if col == 1 {
result.count += filter[c]
}
}
result.id = in.id
result.col = col
chBuf <- in.buf
chResult <- result
}
func main() {
allResults := make([]TempResult, 1024*1024)
cores := 4
chBuf := make(chan []byte, cores)
for i := 0; i < cores; i++ {
chBuf <- make([]byte, 1024*1024)
}
chInput := make(chan Input, cores)
chResult := make(chan TempResult, cores)
id := 0
totalCountChannel := make(chan int)
go func() {
for {
buf := <-chBuf
len, err := os.Stdin.Read(buf)
if err != nil {
break
}
chInput <- Input{id, len, buf}
id++
}
totalCountChannel <- id
}()
for i := 0; i < cores; i++ {
go func() {
for {
partialCount(<-chInput, chBuf, chResult)
}
}()
}
count := 0
consumed := 0
totalCount := -1
for {
var result TempResult
select {
case result = <-chResult:
case totalCount = <-totalCountChannel:
continue
}
rid := result.id
result.id = 1
allResults[rid] = result
count += result.count
if rid == 0 {
count += result.second
} else {
prev := allResults[rid-1]
if prev.id == 1 {
if prev.col == 0 {
count += result.second
} else if prev.col == 1 {
count += result.first
}
}
}
next := allResults[rid+1]
if next.id == 1 {
if result.col == 0 {
count += next.second
} else if result.col == 1 {
count += next.first
}
}
consumed++
if consumed == totalCount {
break
}
}
fmt.Println(count)
}
path = ARGV[0]
filesize = File.size(path)
cores = 4
pipes = Array.new cores do |id|
per = (filesize + cores - 1) / cores
from = per * id
to = [per * (id + 1), filesize].min
rio, wio = IO.pipe
fork do
file = File.open(path, 'r')
file.seek from
length = to - from
length -= file.gets.size if id != 0
count = 0
target = 'aeiou'
s = ''
file.each_line do |line|
length -= line.size
s << line.split(',', 2).last
if s.size > 0x10000
count += s.count target
s = ''
end
break if length < 0
end
wio.puts count + s.count(target)
end
rio
end
puts pipes.map { |io| io.gets.to_i }.sum
File.write 'data.dat', ([%(abc,atmark,123), %(def,colon,456)] * 100 * 10000).join("\n")
% cc -O3 a.c && time ./a.out < data.dat
% go build a.go && time ./a < data.dat
% go build b.go && time ./b < data.dat
% time ./v5.sh < data.dat
% time ruby a.rb < data.dat
% time ruby b.rb data.dat # これだけSTDINじゃなくfileをコマンドライン引数で渡してる
GO B:   0.13s user 0.01s system 327% cpu 0.043 total 25.1倍
C:     0.04s user 0.01s system 93% cpu 0.053 total 20.4倍
GO A:   0.05s user 0.01s system 93% cpu 0.062 total 17.4倍
RUBY B: 2.51s user 0.07s system 329% cpu 0.782 total 1.38倍
SHELL: 1.86s user 0.03s system 175% cpu 1.079 total 基準
RUBY A: 1.28s user 0.05s system 97% cpu 1.363 total 0.79倍
#!/bin/sh
cut -d, -f2 |tr -dc 'aeiou' |wc -c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment