main.s
.global _start
.section .text
_start:
movq (%rsp), %rax
cmp $1, %rax
jle _args_fail # fail if we have 1 or less args
#open the file
movq 16(%rsp), %rdi #filename
xor %rsi, %rsi #flags
xor %rdx, %rdx #mode
movq $2, %rax #open syscall
syscall
#save the fd
movq %rax, .input_file(%rip)
#fstat get info about file
movq %rax, %rdi #file descriptor
movq $5, %rax #fstat syscall
leaq .statbuf(%rip), %rsi #buffer to store the info
syscall
#map the file into memory
movq $9, %rax #mmap syscall
xor %rdi, %rdi
movq .statbuf+48(%rip), %rsi
movq $7, %rdx
movq $2, %r10
movq .input_file(%rip), %r8
movq $0, %r9
syscall
#save the pointer to the maped file.
movq %rax, .mmap_ptr(%rip)
movq %rax, %rsi
movq %rax, %r11 #current item address
movq $0, %r14 #highest sum
before:
movq $0, %r12 #current sum
movq %r11, %rsi
call _get_elf_item_num
cmp $0, %rax
je _done
mov %rax, %r13 #item counter
item_before:
movq %r11, %rsi
call _get_item_as_int #also sets rdi to size of the item
add %rax, %r12
dec %r13
add %rdi, %r11
inc %r11
cmp $0, %r13
jne item_before
_test_:
cmp %r14, %r12
jle _not_bigger
movq %r12,%r14
_not_bigger:
inc %r11
jmp before
_done:
#printf("%d\n", %r14);
movq %r14, %rsi
leaq .printfmt(%rip), %rdi
call printf@PLT
#exit(0);
movq $60, %rax
movq $0, %rdi
syscall
_args_fail:
leaq .args_message(%rip), %rdi
call puts@PLT
mov $1, %rdi
mov $60, %rax
syscall
_get_elf_item_num: #rsi(item_pointer)
movq $0, %r9
_name1:
call _get_item_len
cmp $0, %rax
jne _not_eq
mov %r9, %rax
ret
_not_eq:
add %rax, %rsi
inc %rsi
inc %r9
jmp _name1
_get_item_as_int: #rsi(item_pointer)
call _get_item_len
push %rax
mov %rax, %r10
mov %rsi, %r8
mov $0, %r9
dec %r8
_gogotime:
dec %r10
inc %r8
movq $10, %rdi
movq %r10, %rsi
call _exp
movb (%r8), %dil
sub $'0, %rdi
imulq %rdi, %rax
add %rax, %r9
cmp $1, %r10
jge _gogotime
movq %r9, %rax
pop %rdi
ret
_get_item_len: #rsi(item_pointer)
mov $0, %r10
movq %rsi, %rax
movq .mmap_ptr(%rip), %rdx
add .statbuf+48(%rip), %rdx
sub $1, %rax
loop1:
inc %rax
cmp %rdx, %rax #return if we have reached the end of the file
je __ret1
movb (%rax), %r10b
cmp $'\n', %r10
je __ret1 #if next char is not newline go back
cmp $0, %r10
jne loop1
__ret1:
sub %rsi, %rax
ret
_exp: #rdi^rsi
cmp $0,%rsi
je __is_zero
mov %rdi, %rax
_exp2:
cmp $1, %rsi
jle __ret2
imulq %rdi, %rax
dec %rsi
jmp _exp2
__ret2:
ret
__is_zero:
movq $1, %rax
ret
.section .data
.args_message:
.asciz "file name must be provided"
.printfmt:
.asciz "%d\n"
.section .bss
.lcomm .elf_index 8
.lcomm .read_buf, 256
.lcomm .input_file, 8
.lcomm .statbuf, 144
.lcomm .mmap_ptr, 8
main.c
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char** argv){
if(argc != 2){
fprintf(stderr, "You must provide 1 argument (filename)");
return -1;
}
FILE* fp = fopen(argv[1],"r");
int max_elf_cals = 0;
char* line=NULL;
size_t length=0;
while(1){
int current_elf_cals = 0;
while(1){
if (getline(&line,&length,fp) == -1)
goto end;
if (line==NULL)
goto end;
if(*line=='\n')
break;
current_elf_cals += atoi(line);
free(line);
line=NULL;
}
if(current_elf_cals > max_elf_cals)
max_elf_cals = current_elf_cals;
continue;
end:
if(line)
free(line);
if(current_elf_cals > max_elf_cals)
max_elf_cals = current_elf_cals;
break;
}
printf("%d",max_elf_cals);
return 0;
}
main.rs
use std::fs;
use std::env;
fn main(){
let f_cont = fs::read_to_string(env::args().nth(1).unwrap()).expect("no file");
let mut cur_sum = 0;
let mut max_sum = 0;
for line in f_cont.split("\n"){
if line == "" {
if cur_sum > max_sum {
max_sum = cur_sum;
}
cur_sum = 0;
continue;
}
cur_sum += line.parse::<i32>().unwrap();
}
println!("{}",max_sum);
}
main.rb
#!/usr/bin/ruby
cur_sum=0
max_sum=0
File.foreach(ARGV[0]) { |line|
cur_sum = 0
if line == "\n"
if cur_sum>max_sum
max_sum=cur_sum
end
cur_sum=0
else
cur_sum+=Integer(line)
end
}
puts max_sum
main.py
#! /usr/bin/env python3
import sys
content = open(sys.argv[1]).read().split("\n")
split_list = []
temp_list = []
for i in content:
if(i == ""):
split_list.append(temp_list)
temp_list = []
else:
temp_list.append(i)
max_sum = 0
for i in split_list:
cur_sum = 0
for j in i:
cur_sum+=int(j)
if(cur_sum > max_sum):
max_sum=cur_sum
print(max_sum)
main.hs
import System.IO
import System.Environment
import Control.Monad
import Data.List.Split
main = do
args <- getArgs
handle <- openFile (args !! 0) ReadMode
contents <- hGetContents handle
print $ maximum $ map listSum $ splitOn [""] $ lines contents
hClose handle
listSum :: [String] -> Int
listSum x = sum $ slToIl x
slToIl :: [String] -> [Int]
slToIl = map read
times.txt
time it took for each program to run on a ~500mb file ~90M lines
main.s: 2.818s
main.c: 6.151s
main.rs: 17.665s
main.rb: 41.928
main.py: 57.642s
main.hs: 4m0.190s (used 20gb of ram)